diff --git a/.eslintrc.js b/.eslintrc.js index 35d2da64cc..b09ff37d23 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -63,7 +63,11 @@ module.exports = { customWordListFile: path.resolve(__dirname, '.cspell-wordlist.txt'), }, ], - 'camelcase': 'error', + // `properties: 'never'` lets the lowercase snake_case keys in `models` + // (e.g. `models.text_to_speech.kokoro_small`, mirroring the underlying + // `.pte` filenames) pass while still requiring camelCase for variable + // and function declarations. + 'camelcase': ['error', { properties: 'never' }], 'jsdoc/require-jsdoc': 'off', 'jsdoc/require-param': ['error', { checkDestructured: false }], 'jsdoc/check-param-names': ['error', { checkDestructured: false }], diff --git a/apps/bare-rn/App.tsx b/apps/bare-rn/App.tsx index b7e28658dc..cb6af0aa33 100644 --- a/apps/bare-rn/App.tsx +++ b/apps/bare-rn/App.tsx @@ -13,11 +13,7 @@ import { TouchableWithoutFeedback, View, } from 'react-native'; -import { - initExecutorch, - useLLM, - LLAMA3_2_1B_SPINQUANT, -} from 'react-native-executorch'; +import { models, initExecutorch, useLLM } from 'react-native-executorch'; import { BareResourceFetcher } from 'react-native-executorch-bare-resource-fetcher'; import { setConfig } from '@kesha-antonov/react-native-background-downloader'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; @@ -144,7 +140,9 @@ function App() { const textInputRef = useRef(null); const scrollViewRef = useRef(null); - const llm = useLLM({ model: LLAMA3_2_1B_SPINQUANT }); + const llm = useLLM({ + model: models.llm.lfm2_5_1_2b_instruct(), + }); // Alternatively, to use a custom local model, uncomment below: // const llm = useLLM({ model: { // modelSource: require('./assets/ai-models/smolLm2/smolLm2_135M/smolLm2_135M_bf16.pte'), diff --git a/apps/computer-vision/app/classification/index.tsx b/apps/computer-vision/app/classification/index.tsx index d45e0ddbf8..55a42f7422 100644 --- a/apps/computer-vision/app/classification/index.tsx +++ b/apps/computer-vision/app/classification/index.tsx @@ -1,16 +1,22 @@ import Spinner from '../../components/Spinner'; import { getImage } from '../../utils'; import { + models, useClassification, - EFFICIENTNET_V2_S, - EFFICIENTNET_V2_S_QUANTIZED, ClassificationModelSources, } from 'react-native-executorch'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; +const classification = models.classification; const MODELS: ModelOption[] = [ - { label: 'EfficientNet V2 S Quantized', value: EFFICIENTNET_V2_S_QUANTIZED }, - { label: 'EfficientNet V2 S', value: EFFICIENTNET_V2_S }, + { + label: 'EfficientNet V2 S Quantized', + value: classification.efficientnet_v2_s(), + }, + { + label: 'EfficientNet V2 S', + value: classification.efficientnet_v2_s({ quant: false }), + }, ]; import { View, StyleSheet, Image, Text, ScrollView } from 'react-native'; import { BottomBar } from '../../components/BottomBar'; @@ -22,7 +28,7 @@ import ErrorBanner from '../../components/ErrorBanner'; export default function ClassificationScreen() { const [selectedModel, setSelectedModel] = - useState(EFFICIENTNET_V2_S_QUANTIZED); + useState(classification.efficientnet_v2_s()); const [results, setResults] = useState<{ label: string; score: number }[]>( [] ); diff --git a/apps/computer-vision/app/instance_segmentation/index.tsx b/apps/computer-vision/app/instance_segmentation/index.tsx index f669c383d5..72a4c64506 100644 --- a/apps/computer-vision/app/instance_segmentation/index.tsx +++ b/apps/computer-vision/app/instance_segmentation/index.tsx @@ -3,16 +3,9 @@ import { BottomBar } from '../../components/BottomBar'; import { getImage } from '../../utils'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; import { + models, useInstanceSegmentation, - YOLO26N_SEG, - YOLO26S_SEG, - YOLO26M_SEG, - YOLO26L_SEG, - YOLO26X_SEG, - RF_DETR_NANO_SEG, InstanceSegmentationModelSources, - FASTSAM_S, - FASTSAM_X, } from 'react-native-executorch'; import { View, @@ -29,21 +22,28 @@ import ImageWithMasks, { DisplayInstance, } from '../../components/ImageWithMasks'; import { StatsBar } from '../../components/StatsBar'; +const instanceSegmentation = models.instance_segmentation; +const objectDetection = models.object_detection; const MODELS: ModelOption[] = [ - { label: 'Yolo26N', value: YOLO26N_SEG }, - { label: 'Yolo26S', value: YOLO26S_SEG }, - { label: 'Yolo26M', value: YOLO26M_SEG }, - { label: 'Yolo26L', value: YOLO26L_SEG }, - { label: 'Yolo26X', value: YOLO26X_SEG }, - { label: 'RF-DeTR Nano', value: RF_DETR_NANO_SEG }, - { label: 'FastSAM-S', value: FASTSAM_S }, - { label: 'FastSAM-X', value: FASTSAM_X }, + { label: 'Yolo26N', value: instanceSegmentation.yolo26n_seg() }, + { label: 'Yolo26S', value: instanceSegmentation.yolo26s_seg() }, + { label: 'Yolo26M', value: instanceSegmentation.yolo26m_seg() }, + { label: 'Yolo26L', value: instanceSegmentation.yolo26l_seg() }, + { label: 'Yolo26X', value: instanceSegmentation.yolo26x_seg() }, + { + label: 'RF-DeTR Nano', + value: instanceSegmentation.rf_detr_nano_seg(), + }, + { label: 'FastSAM-S', value: objectDetection.fastsam_s() }, + { label: 'FastSAM-X', value: objectDetection.fastsam_x() }, ]; export default function InstanceSegmentationScreen() { const [selectedModel, setSelectedModel] = - useState(YOLO26N_SEG); + useState( + instanceSegmentation.yolo26n_seg() + ); const [inferenceTime, setInferenceTime] = useState(null); const { setGlobalGenerating } = useContext(GeneratingContext); diff --git a/apps/computer-vision/app/object_detection/index.tsx b/apps/computer-vision/app/object_detection/index.tsx index ea4a9fc7b7..1ed3c136ba 100644 --- a/apps/computer-vision/app/object_detection/index.tsx +++ b/apps/computer-vision/app/object_detection/index.tsx @@ -3,15 +3,9 @@ import { BottomBar } from '../../components/BottomBar'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; import { getImage } from '../../utils'; import { + models, Detection, useObjectDetection, - RF_DETR_NANO, - SSDLITE_320_MOBILENET_V3_LARGE, - YOLO26N, - YOLO26S, - YOLO26M, - YOLO26L, - YOLO26X, ObjectDetectionModelSources, } from 'react-native-executorch'; import { View, StyleSheet, Image, Text } from 'react-native'; @@ -20,15 +14,22 @@ import React, { useContext, useEffect, useState } from 'react'; import { GeneratingContext } from '../../context'; import ScreenWrapper from '../../ScreenWrapper'; import { StatsBar } from '../../components/StatsBar'; +const objectDetection = models.object_detection; const MODELS: ModelOption[] = [ - { label: 'RF-DeTR Nano', value: RF_DETR_NANO }, - { label: 'SSDLite MobileNet', value: SSDLITE_320_MOBILENET_V3_LARGE }, - { label: 'YOLO26N', value: YOLO26N }, - { label: 'YOLO26S', value: YOLO26S }, - { label: 'YOLO26M', value: YOLO26M }, - { label: 'YOLO26L', value: YOLO26L }, - { label: 'YOLO26X', value: YOLO26X }, + { + label: 'RF-DeTR Nano', + value: objectDetection.rf_detr_nano(), + }, + { + label: 'SSDLite MobileNet', + value: objectDetection.ssdlite_320_mobilenet_v3_large(), + }, + { label: 'YOLO26N', value: objectDetection.yolo26n() }, + { label: 'YOLO26S', value: objectDetection.yolo26s() }, + { label: 'YOLO26M', value: objectDetection.yolo26m() }, + { label: 'YOLO26L', value: objectDetection.yolo26l() }, + { label: 'YOLO26X', value: objectDetection.yolo26x() }, ]; import ErrorBanner from '../../components/ErrorBanner'; @@ -41,7 +42,7 @@ export default function ObjectDetectionScreen() { height: number; }>(); const [selectedModel, setSelectedModel] = - useState(RF_DETR_NANO); + useState(objectDetection.rf_detr_nano()); const [inferenceTime, setInferenceTime] = useState(null); const model = useObjectDetection({ model: selectedModel }); diff --git a/apps/computer-vision/app/segment_anything/index.tsx b/apps/computer-vision/app/segment_anything/index.tsx index 037a988327..b4101309c0 100644 --- a/apps/computer-vision/app/segment_anything/index.tsx +++ b/apps/computer-vision/app/segment_anything/index.tsx @@ -21,13 +21,10 @@ import { AlphaType, } from '@shopify/react-native-skia'; import { + models, useInstanceSegmentation, useImageEmbeddings, useTextEmbeddings, - FASTSAM_S, - FASTSAM_X, - CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED, - CLIP_VIT_BASE_PATCH32_TEXT, InstanceSegmentationModelSources, SegmentedInstance, FastSAMLabel, @@ -48,19 +45,20 @@ import ImageWithMasks, { } from '../../components/ImageWithMasks'; import { getImage } from '../../utils'; import ColorPalette from '../../colors'; +const objectDetection = models.object_detection; type PromptMode = 'point' | 'box' | 'text'; const MODELS: ModelOption[] = [ - { label: 'FastSAM-S', value: FASTSAM_S }, - { label: 'FastSAM-X', value: FASTSAM_X }, + { label: 'FastSAM-S', value: objectDetection.fastsam_s() }, + { label: 'FastSAM-X', value: objectDetection.fastsam_x() }, ]; export default function SegmentAnythingScreen() { const { setGlobalGenerating } = useContext(GeneratingContext); const [selectedModel, setSelectedModel] = - useState(FASTSAM_S); + useState(objectDetection.fastsam_s()); const [mode, setMode] = useState('point'); const [inferenceTime, setInferenceTime] = useState(null); @@ -78,9 +76,11 @@ export default function SegmentAnythingScreen() { useInstanceSegmentation({ model: selectedModel }); const clipImage = useImageEmbeddings({ - model: CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED, + model: models.image_embedding.clip_vit_base_patch32_image(), + }); + const clipText = useTextEmbeddings({ + model: models.text_embedding.clip_vit_base_patch32_text(), }); - const clipText = useTextEmbeddings({ model: CLIP_VIT_BASE_PATCH32_TEXT }); const skiaSource = useImage(imageUri || null); const [textPrompt, setTextPrompt] = useState(''); diff --git a/apps/computer-vision/app/semantic_segmentation/index.tsx b/apps/computer-vision/app/semantic_segmentation/index.tsx index ba998bca2a..f77c8de9c8 100644 --- a/apps/computer-vision/app/semantic_segmentation/index.tsx +++ b/apps/computer-vision/app/semantic_segmentation/index.tsx @@ -3,13 +3,7 @@ import { BottomBar } from '../../components/BottomBar'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; import { getImage } from '../../utils'; import { - DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, - DEEPLAB_V3_RESNET50_QUANTIZED, - DEEPLAB_V3_RESNET101_QUANTIZED, - LRASPP_MOBILENET_V3_LARGE_QUANTIZED, - FCN_RESNET50_QUANTIZED, - FCN_RESNET101_QUANTIZED, - SELFIE_SEGMENTATION, + models, useSemanticSegmentation, SemanticSegmentationModelSources, } from 'react-native-executorch'; @@ -27,6 +21,7 @@ import { GeneratingContext } from '../../context'; import ScreenWrapper from '../../ScreenWrapper'; import { StatsBar } from '../../components/StatsBar'; import ErrorBanner from '../../components/ErrorBanner'; +const semanticSegmentation = models.semantic_segmentation; const numberToColor: number[][] = [ [255, 87, 51], // 0 Red @@ -55,21 +50,39 @@ const numberToColor: number[][] = [ const MODELS: ModelOption[] = [ { label: 'DeepLab MobileNet', - value: DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, + value: semanticSegmentation.deeplab_v3_mobilenet_v3_large(), + }, + { + label: 'DeepLab ResNet50', + value: semanticSegmentation.deeplab_v3_resnet50(), + }, + { + label: 'DeepLab ResNet101', + value: semanticSegmentation.deeplab_v3_resnet101(), + }, + { + label: 'LRASPP MobileNet', + value: semanticSegmentation.lraspp_mobilenet_v3_large(), + }, + { + label: 'FCN ResNet50', + value: semanticSegmentation.fcn_resnet50(), + }, + { + label: 'FCN ResNet101', + value: semanticSegmentation.fcn_resnet101(), + }, + { + label: 'Selfie Segmentation', + value: semanticSegmentation.selfie_segmentation(), }, - { label: 'DeepLab ResNet50', value: DEEPLAB_V3_RESNET50_QUANTIZED }, - { label: 'DeepLab ResNet101', value: DEEPLAB_V3_RESNET101_QUANTIZED }, - { label: 'LRASPP MobileNet', value: LRASPP_MOBILENET_V3_LARGE_QUANTIZED }, - { label: 'FCN ResNet50', value: FCN_RESNET50_QUANTIZED }, - { label: 'FCN ResNet101', value: FCN_RESNET101_QUANTIZED }, - { label: 'Selfie Segmentation', value: SELFIE_SEGMENTATION }, ]; export default function SemanticSegmentationScreen() { const { setGlobalGenerating } = useContext(GeneratingContext); const [selectedModel, setSelectedModel] = useState( - DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED + semanticSegmentation.deeplab_v3_mobilenet_v3_large() ); const { diff --git a/apps/computer-vision/app/style_transfer/index.tsx b/apps/computer-vision/app/style_transfer/index.tsx index 8770087067..d8eda655f7 100644 --- a/apps/computer-vision/app/style_transfer/index.tsx +++ b/apps/computer-vision/app/style_transfer/index.tsx @@ -3,11 +3,8 @@ import { BottomBar } from '../../components/BottomBar'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; import { getImage } from '../../utils'; import { + models, useStyleTransfer, - STYLE_TRANSFER_CANDY_QUANTIZED, - STYLE_TRANSFER_MOSAIC_QUANTIZED, - STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED, - STYLE_TRANSFER_UDNIE_QUANTIZED, StyleTransferModelName, ResourceSource, } from 'react-native-executorch'; @@ -18,6 +15,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { GeneratingContext } from '../../context'; import ScreenWrapper from '../../ScreenWrapper'; import { StatsBar } from '../../components/StatsBar'; +const styleTransfer = models.style_transfer; type StyleTransferModelSources = { modelName: StyleTransferModelName; @@ -25,16 +23,19 @@ type StyleTransferModelSources = { }; const MODELS: ModelOption[] = [ - { label: 'Candy', value: STYLE_TRANSFER_CANDY_QUANTIZED }, - { label: 'Mosaic', value: STYLE_TRANSFER_MOSAIC_QUANTIZED }, - { label: 'Rain Princess', value: STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED }, - { label: 'Udnie', value: STYLE_TRANSFER_UDNIE_QUANTIZED }, + { label: 'Candy', value: styleTransfer.candy() }, + { label: 'Mosaic', value: styleTransfer.mosaic() }, + { + label: 'Rain Princess', + value: styleTransfer.rain_princess(), + }, + { label: 'Udnie', value: styleTransfer.udnie() }, ]; import ErrorBanner from '../../components/ErrorBanner'; export default function StyleTransferScreen() { const [selectedModel, setSelectedModel] = useState( - STYLE_TRANSFER_CANDY_QUANTIZED + styleTransfer.candy() ); const model = useStyleTransfer({ model: selectedModel }); diff --git a/apps/computer-vision/app/text_to_image/index.tsx b/apps/computer-vision/app/text_to_image/index.tsx index 6af71227e9..47fce1e8b6 100644 --- a/apps/computer-vision/app/text_to_image/index.tsx +++ b/apps/computer-vision/app/text_to_image/index.tsx @@ -14,9 +14,8 @@ import React, { useContext, useEffect, useState } from 'react'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Spinner from '../../components/Spinner'; import { + models, useTextToImage, - BK_SDM_TINY_VPRED_256, - BK_SDM_TINY_VPRED_512, TextToImageProps, } from 'react-native-executorch'; import { ModelPicker, ModelOption } from '../../components/ModelPicker'; @@ -26,12 +25,19 @@ import ProgressBar from '../../components/ProgressBar'; import { Ionicons } from '@expo/vector-icons'; import { StatsBar } from '../../components/StatsBar'; import ErrorBanner from '../../components/ErrorBanner'; +const imageGeneration = models.image_generation; type TextToImageModelSources = TextToImageProps['model']; const MODELS: ModelOption[] = [ - { label: 'BK-SDM 256', value: BK_SDM_TINY_VPRED_256 }, - { label: 'BK-SDM 512', value: BK_SDM_TINY_VPRED_512 }, + { + label: 'BK-SDM 256', + value: imageGeneration.bk_sdm_tiny_vpred_256(), + }, + { + label: 'BK-SDM 512', + value: imageGeneration.bk_sdm_tiny_vpred_512(), + }, ]; export default function TextToImageScreen() { @@ -42,7 +48,7 @@ export default function TextToImageScreen() { const [input, setInput] = useState(''); const [selectedModel, setSelectedModel] = useState( - BK_SDM_TINY_VPRED_256 + imageGeneration.bk_sdm_tiny_vpred_256() ); const [generationTime, setGenerationTime] = useState(null); diff --git a/apps/computer-vision/components/vision_camera/tasks/ClassificationTask.tsx b/apps/computer-vision/components/vision_camera/tasks/ClassificationTask.tsx index ef0046a297..e5b2f3ad3f 100644 --- a/apps/computer-vision/components/vision_camera/tasks/ClassificationTask.tsx +++ b/apps/computer-vision/components/vision_camera/tasks/ClassificationTask.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { Frame, useFrameOutput } from 'react-native-vision-camera'; import { scheduleOnRN } from 'react-native-worklets'; -import { EFFICIENTNET_V2_S, useClassification } from 'react-native-executorch'; +import { models, useClassification } from 'react-native-executorch'; import { FRAME_TARGET_RESOLUTION, TaskProps } from './types'; type Props = Omit< @@ -19,7 +19,9 @@ export default function ClassificationTask({ onFpsChange, onErrorChange, }: Props) { - const model = useClassification({ model: EFFICIENTNET_V2_S }); + const model = useClassification({ + model: models.classification.efficientnet_v2_s(), + }); const [classResult, setClassResult] = useState({ label: '', score: 0 }); const lastFrameTimeRef = useRef(Date.now()); diff --git a/apps/computer-vision/components/vision_camera/tasks/InstanceSegmentationTask.tsx b/apps/computer-vision/components/vision_camera/tasks/InstanceSegmentationTask.tsx index 52251f6e3e..478cb25732 100644 --- a/apps/computer-vision/components/vision_camera/tasks/InstanceSegmentationTask.tsx +++ b/apps/computer-vision/components/vision_camera/tasks/InstanceSegmentationTask.tsx @@ -3,11 +3,8 @@ import { StyleSheet, Text, View } from 'react-native'; import { Frame, useFrameOutput } from 'react-native-vision-camera'; import { scheduleOnRN } from 'react-native-worklets'; import { + models, SegmentedInstance, - YOLO26N_SEG, - RF_DETR_NANO_SEG, - FASTSAM_S, - FASTSAM_X, useInstanceSegmentation, CocoLabel, CocoLabelYolo, @@ -20,6 +17,8 @@ import { buildDisplayInstances, DisplayInstance, } from '../../../components/ImageWithMasks'; +const instanceSegmentation = models.instance_segmentation; +const objectDetection = models.object_detection; type InstSegModelId = | 'instanceSegmentationYolo26n' @@ -42,19 +41,19 @@ export default function InstanceSegmentationTask({ onErrorChange, }: Props) { const yolo26n = useInstanceSegmentation({ - model: YOLO26N_SEG, + model: instanceSegmentation.yolo26n_seg(), preventLoad: activeModel !== 'instanceSegmentationYolo26n', }); const rfdetr = useInstanceSegmentation({ - model: RF_DETR_NANO_SEG, + model: instanceSegmentation.rf_detr_nano_seg(), preventLoad: activeModel !== 'instanceSegmentationRfdetr', }); const fastsamS = useInstanceSegmentation({ - model: FASTSAM_S, + model: objectDetection.fastsam_s(), preventLoad: activeModel !== 'instanceSegmentationFastsamS', }); const fastsamX = useInstanceSegmentation({ - model: FASTSAM_X, + model: objectDetection.fastsam_x(), preventLoad: activeModel !== 'instanceSegmentationFastsamX', }); diff --git a/apps/computer-vision/components/vision_camera/tasks/ObjectDetectionTask.tsx b/apps/computer-vision/components/vision_camera/tasks/ObjectDetectionTask.tsx index 992a8eaad0..e05de26105 100644 --- a/apps/computer-vision/components/vision_camera/tasks/ObjectDetectionTask.tsx +++ b/apps/computer-vision/components/vision_camera/tasks/ObjectDetectionTask.tsx @@ -3,16 +3,15 @@ import { StyleSheet, View } from 'react-native'; import { Frame, useFrameOutput } from 'react-native-vision-camera'; import { scheduleOnRN } from 'react-native-worklets'; import { + models, Detection, - RF_DETR_NANO, - SSDLITE_320_MOBILENET_V3_LARGE, - YOLO26N, useObjectDetection, CocoLabel, CocoLabelYolo, } from 'react-native-executorch'; import BoundingBoxes from '../../BoundingBoxes'; import { FRAME_TARGET_RESOLUTION, TaskProps } from './types'; +const objectDetection = models.object_detection; type ObjModelId = | 'objectDetectionSsdlite' @@ -34,15 +33,15 @@ export default function ObjectDetectionTask({ onErrorChange, }: Props) { const ssdlite = useObjectDetection({ - model: SSDLITE_320_MOBILENET_V3_LARGE, + model: objectDetection.ssdlite_320_mobilenet_v3_large(), preventLoad: activeModel !== 'objectDetectionSsdlite', }); const rfdetr = useObjectDetection({ - model: RF_DETR_NANO, + model: objectDetection.rf_detr_nano(), preventLoad: activeModel !== 'objectDetectionRfdetr', }); const yolo26n = useObjectDetection({ - model: YOLO26N, + model: objectDetection.yolo26n(), preventLoad: activeModel !== 'objectDetectionYolo26n', }); diff --git a/apps/computer-vision/components/vision_camera/tasks/SegmentationTask.tsx b/apps/computer-vision/components/vision_camera/tasks/SegmentationTask.tsx index b06f2ff9d1..b88e457b23 100644 --- a/apps/computer-vision/components/vision_camera/tasks/SegmentationTask.tsx +++ b/apps/computer-vision/components/vision_camera/tasks/SegmentationTask.tsx @@ -2,16 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Frame, useFrameOutput } from 'react-native-vision-camera'; import { scheduleOnRN } from 'react-native-worklets'; -import { - DEEPLAB_V3_RESNET50_QUANTIZED, - DEEPLAB_V3_RESNET101_QUANTIZED, - DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, - FCN_RESNET50_QUANTIZED, - FCN_RESNET101_QUANTIZED, - LRASPP_MOBILENET_V3_LARGE_QUANTIZED, - SELFIE_SEGMENTATION, - useSemanticSegmentation, -} from 'react-native-executorch'; +import { models, useSemanticSegmentation } from 'react-native-executorch'; import { AlphaType, Canvas, @@ -22,6 +13,7 @@ import { } from '@shopify/react-native-skia'; import { CLASS_COLORS } from '../../utils/colors'; import { FRAME_TARGET_RESOLUTION, TaskProps } from './types'; +const semanticSegmentation = models.semantic_segmentation; type SegModelId = | 'segmentationDeeplabResnet50' @@ -47,31 +39,31 @@ export default function SegmentationTask({ onErrorChange, }: Props) { const segDeeplabResnet50 = useSemanticSegmentation({ - model: DEEPLAB_V3_RESNET50_QUANTIZED, + model: semanticSegmentation.deeplab_v3_resnet50(), preventLoad: activeModel !== 'segmentationDeeplabResnet50', }); const segDeeplabResnet101 = useSemanticSegmentation({ - model: DEEPLAB_V3_RESNET101_QUANTIZED, + model: semanticSegmentation.deeplab_v3_resnet101(), preventLoad: activeModel !== 'segmentationDeeplabResnet101', }); const segDeeplabMobilenet = useSemanticSegmentation({ - model: DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, + model: semanticSegmentation.deeplab_v3_mobilenet_v3_large(), preventLoad: activeModel !== 'segmentationDeeplabMobilenet', }); const segLraspp = useSemanticSegmentation({ - model: LRASPP_MOBILENET_V3_LARGE_QUANTIZED, + model: semanticSegmentation.lraspp_mobilenet_v3_large(), preventLoad: activeModel !== 'segmentationLraspp', }); const segFcnResnet50 = useSemanticSegmentation({ - model: FCN_RESNET50_QUANTIZED, + model: semanticSegmentation.fcn_resnet50(), preventLoad: activeModel !== 'segmentationFcnResnet50', }); const segFcnResnet101 = useSemanticSegmentation({ - model: FCN_RESNET101_QUANTIZED, + model: semanticSegmentation.fcn_resnet101(), preventLoad: activeModel !== 'segmentationFcnResnet101', }); const segSelfie = useSemanticSegmentation({ - model: SELFIE_SEGMENTATION, + model: semanticSegmentation.selfie_segmentation(), preventLoad: activeModel !== 'segmentationSelfie', }); diff --git a/apps/computer-vision/components/vision_camera/tasks/StyleTransferTask.tsx b/apps/computer-vision/components/vision_camera/tasks/StyleTransferTask.tsx index 6361970bfc..d5f8578272 100644 --- a/apps/computer-vision/components/vision_camera/tasks/StyleTransferTask.tsx +++ b/apps/computer-vision/components/vision_camera/tasks/StyleTransferTask.tsx @@ -2,11 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Frame, useFrameOutput } from 'react-native-vision-camera'; import { scheduleOnRN } from 'react-native-worklets'; -import { - STYLE_TRANSFER_CANDY, - STYLE_TRANSFER_MOSAIC, - useStyleTransfer, -} from 'react-native-executorch'; +import { models, useStyleTransfer } from 'react-native-executorch'; import { AlphaType, Canvas, @@ -16,6 +12,7 @@ import { SkImage, } from '@shopify/react-native-skia'; import { FRAME_TARGET_RESOLUTION, TaskProps } from './types'; +const styleTransfer = models.style_transfer; type StyleModelId = 'styleTransferCandy' | 'styleTransferMosaic'; @@ -34,11 +31,11 @@ export default function StyleTransferTask({ onErrorChange, }: Props) { const candy = useStyleTransfer({ - model: STYLE_TRANSFER_CANDY, + model: styleTransfer.candy(), preventLoad: activeModel !== 'styleTransferCandy', }); const mosaic = useStyleTransfer({ - model: STYLE_TRANSFER_MOSAIC, + model: styleTransfer.mosaic(), preventLoad: activeModel !== 'styleTransferMosaic', }); diff --git a/apps/llm/app/llm/index.tsx b/apps/llm/app/llm/index.tsx index 901b74de43..907cd5f538 100644 --- a/apps/llm/app/llm/index.tsx +++ b/apps/llm/app/llm/index.tsx @@ -11,7 +11,7 @@ import { View, } from 'react-native'; import SendIcon from '../../assets/icons/send_icon.svg'; -import { useLLM, LLAMA3_2_1B_SPINQUANT } from 'react-native-executorch'; +import { models, useLLM } from 'react-native-executorch'; import { ModelPicker } from '../../components/ModelPicker'; import { LLM_MODELS, LLMModelSources } from '../../components/llmModels'; import PauseIcon from '../../assets/icons/pause_icon.svg'; @@ -43,7 +43,7 @@ function LLMScreen() { const [isTextInputFocused, setIsTextInputFocused] = useState(false); const [userInput, setUserInput] = useState(''); const [selectedModel, setSelectedModel] = useState( - LLAMA3_2_1B_SPINQUANT + models.llm.llama3_2_1b() ); const textInputRef = useRef(null); const { setGlobalGenerating } = useContext(GeneratingContext); diff --git a/apps/llm/app/llm_structured_output/index.tsx b/apps/llm/app/llm_structured_output/index.tsx index aea47b8136..8150da4d6c 100644 --- a/apps/llm/app/llm_structured_output/index.tsx +++ b/apps/llm/app/llm_structured_output/index.tsx @@ -24,10 +24,10 @@ import { useLLMStats } from '../../hooks/useLLMStats'; import { StatsBar } from '../../components/StatsBar'; import ErrorBanner from '../../components/ErrorBanner'; import { + models, useLLM, fixAndValidateStructuredOutput, getStructuredOutputPrompt, - QWEN3_1_7B_QUANTIZED, } from 'react-native-executorch'; import { ModelPicker } from '../../components/ModelPicker'; import { LLM_MODELS, LLMModelSources } from '../../components/llmModels'; @@ -83,8 +83,9 @@ export default function LLMScreenWrapper() { function LLMScreen() { const [isTextInputFocused, setIsTextInputFocused] = useState(false); const [userInput, setUserInput] = useState(''); - const [selectedModel, setSelectedModel] = - useState(QWEN3_1_7B_QUANTIZED); + const [selectedModel, setSelectedModel] = useState( + models.llm.qwen3_1_7b() + ); const textInputRef = useRef(null); const { setGlobalGenerating } = useContext(GeneratingContext); diff --git a/apps/llm/app/llm_tool_calling/index.tsx b/apps/llm/app/llm_tool_calling/index.tsx index 2ef688ed69..f059d59793 100644 --- a/apps/llm/app/llm_tool_calling/index.tsx +++ b/apps/llm/app/llm_tool_calling/index.tsx @@ -17,11 +17,7 @@ import SWMIcon from '../../assets/icons/swm_icon.svg'; import SendIcon from '../../assets/icons/send_icon.svg'; import Spinner from '../../components/Spinner'; import ErrorBanner from '../../components/ErrorBanner'; -import { - useLLM, - DEFAULT_SYSTEM_PROMPT, - HAMMER2_1_1_5B_QUANTIZED, -} from 'react-native-executorch'; +import { models, useLLM, DEFAULT_SYSTEM_PROMPT } from 'react-native-executorch'; import { ModelPicker } from '../../components/ModelPicker'; import { LLM_MODELS, LLMModelSources } from '../../components/llmModels'; import PauseIcon from '../../assets/icons/pause_icon.svg'; @@ -55,7 +51,7 @@ function LLMToolCallingScreen() { const [hasCalendarPermission, setHasCalendarPermission] = useState(true); const [hasBrightnessPermission, setHasBrightnessPermission] = useState(true); const [selectedModel, setSelectedModel] = useState( - HAMMER2_1_1_5B_QUANTIZED + models.llm.hammer2_1_1_5b() ); const textInputRef = useRef(null); const { setGlobalGenerating } = useContext(GeneratingContext); diff --git a/apps/llm/app/multimodal_llm/index.tsx b/apps/llm/app/multimodal_llm/index.tsx index b7d6859ede..408798e967 100644 --- a/apps/llm/app/multimodal_llm/index.tsx +++ b/apps/llm/app/multimodal_llm/index.tsx @@ -14,7 +14,7 @@ import { import { launchImageLibrary } from 'react-native-image-picker'; import { useIsFocused } from '@react-navigation/native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { useLLM, LFM2_5_VL_1_6B_QUANTIZED } from 'react-native-executorch'; +import { models, useLLM } from 'react-native-executorch'; import SendIcon from '../../assets/icons/send_icon.svg'; import PauseIcon from '../../assets/icons/pause_icon.svg'; import ColorPalette from '../../colors'; @@ -50,7 +50,7 @@ function MultimodalLLMScreen() { const [error, setError] = useState(null); const vlm = useLLM({ - model: LFM2_5_VL_1_6B_QUANTIZED, + model: models.multimodal.lfm2_5_vl_1_6b(), }); const tokenCount = vlm.isReady ? vlm.getGeneratedTokenCount() : 0; const { stats, onMessageSend } = useLLMStats( diff --git a/apps/llm/app/voice_chat/index.tsx b/apps/llm/app/voice_chat/index.tsx index 23ab70bff4..23a18eaec7 100644 --- a/apps/llm/app/voice_chat/index.tsx +++ b/apps/llm/app/voice_chat/index.tsx @@ -13,15 +13,9 @@ import SWMIcon from '../../assets/icons/swm_icon.svg'; import Spinner from '../../components/Spinner'; import ErrorBanner from '../../components/ErrorBanner'; import { + models, useSpeechToText, useLLM, - QWEN3_0_6B_QUANTIZED, - QWEN3_1_7B_QUANTIZED, - LLAMA3_2_1B_SPINQUANT, - WHISPER_TINY_EN, - WHISPER_TINY_EN_QUANTIZED, - WHISPER_BASE_EN, - WHISPER_SMALL_EN, LLMProps, SpeechToTextProps, } from 'react-native-executorch'; @@ -41,16 +35,28 @@ type LLMModelSources = LLMProps['model']; type STTModelSources = SpeechToTextProps['model']; const LLM_MODELS: ModelOption[] = [ - { label: 'Qwen3 0.6B', value: QWEN3_0_6B_QUANTIZED }, - { label: 'Qwen3 1.7B', value: QWEN3_1_7B_QUANTIZED }, - { label: 'Llama 1B', value: LLAMA3_2_1B_SPINQUANT }, + { label: 'Qwen3 0.6B', value: models.llm.qwen3_0_6b() }, + { label: 'Qwen3 1.7B', value: models.llm.qwen3_1_7b() }, + { label: 'Llama 1B', value: models.llm.llama3_2_1b() }, ]; const STT_MODELS: ModelOption[] = [ - { label: 'Whisper Tiny', value: WHISPER_TINY_EN }, - { label: 'Whisper Tiny Q', value: WHISPER_TINY_EN_QUANTIZED }, - { label: 'Whisper Base', value: WHISPER_BASE_EN }, - { label: 'Whisper Small', value: WHISPER_SMALL_EN }, + { + label: 'Whisper Tiny', + value: models.speech_to_text.whisper_tiny_en({ quant: false }), + }, + { + label: 'Whisper Tiny Q', + value: models.speech_to_text.whisper_tiny_en(), + }, + { + label: 'Whisper Base', + value: models.speech_to_text.whisper_base_en(), + }, + { + label: 'Whisper Small', + value: models.speech_to_text.whisper_small_en(), + }, ]; export default function VoiceChatScreenWrapper() { @@ -63,10 +69,12 @@ function VoiceChatScreen() { const { bottom } = useSafeAreaInsets(); const [isRecording, setIsRecording] = useState(false); const [liveTranscription, setLiveTranscription] = useState(''); - const [selectedLLM, setSelectedLLM] = - useState(QWEN3_0_6B_QUANTIZED); - const [selectedSTT, setSelectedSTT] = - useState(WHISPER_TINY_EN); + const [selectedLLM, setSelectedLLM] = useState( + models.llm.qwen3_0_6b() + ); + const [selectedSTT, setSelectedSTT] = useState( + models.speech_to_text.whisper_tiny_en({ quant: false }) + ); const [error, setError] = useState(null); const [recorder] = useState(() => new AudioRecorder()); diff --git a/apps/llm/components/llmModels.ts b/apps/llm/components/llmModels.ts index 593db478b3..1d80d7a395 100644 --- a/apps/llm/components/llmModels.ts +++ b/apps/llm/components/llmModels.ts @@ -1,101 +1,146 @@ import { - LLAMA3_2_1B, + models, LLAMA3_2_1B_QLORA, - LLAMA3_2_1B_SPINQUANT, - LLAMA3_2_3B, LLAMA3_2_3B_QLORA, - LLAMA3_2_3B_SPINQUANT, - QWEN3_0_6B, - QWEN3_0_6B_QUANTIZED, - QWEN3_1_7B, - QWEN3_1_7B_QUANTIZED, - QWEN3_4B, - QWEN3_4B_QUANTIZED, - HAMMER2_1_0_5B, - HAMMER2_1_0_5B_QUANTIZED, - HAMMER2_1_1_5B, - HAMMER2_1_1_5B_QUANTIZED, - HAMMER2_1_3B, - HAMMER2_1_3B_QUANTIZED, - SMOLLM2_1_135M, - SMOLLM2_1_135M_QUANTIZED, - SMOLLM2_1_360M, - SMOLLM2_1_360M_QUANTIZED, - SMOLLM2_1_1_7B, - SMOLLM2_1_1_7B_QUANTIZED, - QWEN2_5_0_5B, - QWEN2_5_0_5B_QUANTIZED, - QWEN2_5_1_5B, - QWEN2_5_1_5B_QUANTIZED, - QWEN2_5_3B, - QWEN2_5_3B_QUANTIZED, - PHI_4_MINI_4B, - PHI_4_MINI_4B_QUANTIZED, - LFM2_5_350M, - LFM2_5_350M_QUANTIZED, - LFM2_5_1_2B_INSTRUCT, - LFM2_5_1_2B_INSTRUCT_QUANTIZED, LLMProps, - QWEN3_5_0_8B_QUANTIZED, - QWEN3_5_2B_QUANTIZED, - BIELIK_V3_0_1_5B_QUANTIZED, - BIELIK_V3_0_1_5B, } from 'react-native-executorch'; import { ModelOption } from './ModelPicker'; +const llm = models.llm; export type LLMModelSources = LLMProps['model']; export const LLM_MODELS: ModelOption[] = [ // Llama 3.2 - { label: 'Llama 3.2 1B', value: LLAMA3_2_1B }, + { + label: 'Llama 3.2 1B', + value: llm.llama3_2_1b({ quant: false }), + }, { label: 'Llama 3.2 1B QLoRA', value: LLAMA3_2_1B_QLORA }, - { label: 'Llama 3.2 1B SpinQuant', value: LLAMA3_2_1B_SPINQUANT }, - { label: 'Llama 3.2 3B', value: LLAMA3_2_3B }, + { label: 'Llama 3.2 1B SpinQuant', value: llm.llama3_2_1b() }, + { + label: 'Llama 3.2 3B', + value: llm.llama3_2_3b({ quant: false }), + }, { label: 'Llama 3.2 3B QLoRA', value: LLAMA3_2_3B_QLORA }, - { label: 'Llama 3.2 3B SpinQuant', value: LLAMA3_2_3B_SPINQUANT }, + { label: 'Llama 3.2 3B SpinQuant', value: llm.llama3_2_3b() }, // Qwen3 - { label: 'Qwen3 0.6B', value: QWEN3_0_6B }, - { label: 'Qwen3 0.6B Quantized', value: QWEN3_0_6B_QUANTIZED }, - { label: 'Qwen3 1.7B', value: QWEN3_1_7B }, - { label: 'Qwen3 1.7B Quantized', value: QWEN3_1_7B_QUANTIZED }, - { label: 'Qwen3 4B', value: QWEN3_4B }, - { label: 'Qwen3 4B Quantized', value: QWEN3_4B_QUANTIZED }, + { + label: 'Qwen3 0.6B', + value: llm.qwen3_0_6b({ quant: false }), + }, + { label: 'Qwen3 0.6B Quantized', value: llm.qwen3_0_6b() }, + { + label: 'Qwen3 1.7B', + value: llm.qwen3_1_7b({ quant: false }), + }, + { label: 'Qwen3 1.7B Quantized', value: llm.qwen3_1_7b() }, + { label: 'Qwen3 4B', value: llm.qwen3_4b({ quant: false }) }, + { label: 'Qwen3 4B Quantized', value: llm.qwen3_4b() }, // Hammer 2.1 - { label: 'Hammer 2.1 0.5B', value: HAMMER2_1_0_5B }, - { label: 'Hammer 2.1 0.5B Quantized', value: HAMMER2_1_0_5B_QUANTIZED }, - { label: 'Hammer 2.1 1.5B', value: HAMMER2_1_1_5B }, - { label: 'Hammer 2.1 1.5B Quantized', value: HAMMER2_1_1_5B_QUANTIZED }, - { label: 'Hammer 2.1 3B', value: HAMMER2_1_3B }, - { label: 'Hammer 2.1 3B Quantized', value: HAMMER2_1_3B_QUANTIZED }, + { + label: 'Hammer 2.1 0.5B', + value: llm.hammer2_1_0_5b({ quant: false }), + }, + { + label: 'Hammer 2.1 0.5B Quantized', + value: llm.hammer2_1_0_5b(), + }, + { + label: 'Hammer 2.1 1.5B', + value: llm.hammer2_1_1_5b({ quant: false }), + }, + { + label: 'Hammer 2.1 1.5B Quantized', + value: llm.hammer2_1_1_5b(), + }, + { + label: 'Hammer 2.1 3B', + value: llm.hammer2_1_3b({ quant: false }), + }, + { + label: 'Hammer 2.1 3B Quantized', + value: llm.hammer2_1_3b(), + }, // SmolLM2 - { label: 'SmolLM2 135M', value: SMOLLM2_1_135M }, - { label: 'SmolLM2 135M Quantized', value: SMOLLM2_1_135M_QUANTIZED }, - { label: 'SmolLM2 360M', value: SMOLLM2_1_360M }, - { label: 'SmolLM2 360M Quantized', value: SMOLLM2_1_360M_QUANTIZED }, - { label: 'SmolLM2 1.7B', value: SMOLLM2_1_1_7B }, - { label: 'SmolLM2 1.7B Quantized', value: SMOLLM2_1_1_7B_QUANTIZED }, + { + label: 'SmolLM2 135M', + value: llm.smollm2_1_135m({ quant: false }), + }, + { + label: 'SmolLM2 135M Quantized', + value: llm.smollm2_1_135m(), + }, + { + label: 'SmolLM2 360M', + value: llm.smollm2_1_360m({ quant: false }), + }, + { + label: 'SmolLM2 360M Quantized', + value: llm.smollm2_1_360m(), + }, + { + label: 'SmolLM2 1.7B', + value: llm.smollm2_1_1_7b({ quant: false }), + }, + { + label: 'SmolLM2 1.7B Quantized', + value: llm.smollm2_1_1_7b(), + }, // Qwen2.5 - { label: 'Qwen2.5 0.5B', value: QWEN2_5_0_5B }, - { label: 'Qwen2.5 0.5B Quantized', value: QWEN2_5_0_5B_QUANTIZED }, - { label: 'Qwen2.5 1.5B', value: QWEN2_5_1_5B }, - { label: 'Qwen2.5 1.5B Quantized', value: QWEN2_5_1_5B_QUANTIZED }, - { label: 'Qwen2.5 3B', value: QWEN2_5_3B }, - { label: 'Qwen2.5 3B Quantized', value: QWEN2_5_3B_QUANTIZED }, + { + label: 'Qwen2.5 0.5B', + value: llm.qwen2_5_0_5b({ quant: false }), + }, + { + label: 'Qwen2.5 0.5B Quantized', + value: llm.qwen2_5_0_5b(), + }, + { + label: 'Qwen2.5 1.5B', + value: llm.qwen2_5_1_5b({ quant: false }), + }, + { + label: 'Qwen2.5 1.5B Quantized', + value: llm.qwen2_5_1_5b(), + }, + { + label: 'Qwen2.5 3B', + value: llm.qwen2_5_3b({ quant: false }), + }, + { label: 'Qwen2.5 3B Quantized', value: llm.qwen2_5_3b() }, // Qwen3.5 - { label: 'Qwen3.5 0.8B Quantized', value: QWEN3_5_0_8B_QUANTIZED }, - { label: 'Qwen3.5 2B Quantized', value: QWEN3_5_2B_QUANTIZED }, + { label: 'Qwen3.5 0.8B Quantized', value: llm.qwen3_5_0_8b() }, + { label: 'Qwen3.5 2B Quantized', value: llm.qwen3_5_2b() }, // Phi-4 - { label: 'Phi-4 Mini 4B', value: PHI_4_MINI_4B }, - { label: 'Phi-4 Mini 4B Quantized', value: PHI_4_MINI_4B_QUANTIZED }, + { + label: 'Phi-4 Mini 4B', + value: llm.phi_4_mini_4b({ quant: false }), + }, + { + label: 'Phi-4 Mini 4B Quantized', + value: llm.phi_4_mini_4b(), + }, // LFM2.5 - { label: 'LFM2.5 350M', value: LFM2_5_350M }, - { label: 'LFM2.5 350M Quantized', value: LFM2_5_350M_QUANTIZED }, - { label: 'LFM2.5 1.2B Instruct', value: LFM2_5_1_2B_INSTRUCT }, + { + label: 'LFM2.5 350M', + value: llm.lfm2_5_350m({ quant: false }), + }, + { label: 'LFM2.5 350M Quantized', value: llm.lfm2_5_350m() }, + { + label: 'LFM2.5 1.2B Instruct', + value: llm.lfm2_5_1_2b_instruct({ quant: false }), + }, { label: 'LFM2.5 1.2B Instruct Quantized', - value: LFM2_5_1_2B_INSTRUCT_QUANTIZED, + value: llm.lfm2_5_1_2b_instruct(), }, // Bielik v3.0 - { label: 'Bielik v3.0 1.5B', value: BIELIK_V3_0_1_5B }, - { label: 'Bielik v3.0 1.5B Quantized', value: BIELIK_V3_0_1_5B_QUANTIZED }, + { + label: 'Bielik v3.0 1.5B', + value: llm.bielik_v3_0_1_5b({ quant: false }), + }, + { + label: 'Bielik v3.0 1.5B Quantized', + value: llm.bielik_v3_0_1_5b(), + }, ]; diff --git a/apps/speech/screens/SpeechToTextScreen.tsx b/apps/speech/screens/SpeechToTextScreen.tsx index dfd39c15b4..532ccfd59e 100644 --- a/apps/speech/screens/SpeechToTextScreen.tsx +++ b/apps/speech/screens/SpeechToTextScreen.tsx @@ -12,23 +12,33 @@ import { } from 'react-native'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; import { + models, useSpeechToText, - WHISPER_TINY_EN, - WHISPER_TINY_EN_QUANTIZED, - WHISPER_BASE_EN, - WHISPER_SMALL_EN, TranscriptionResult, SpeechToTextProps, } from 'react-native-executorch'; import { ModelPicker, ModelOption } from '../components/ModelPicker'; +const speechToText = models.speech_to_text; type STTModelSources = SpeechToTextProps['model']; const MODELS: ModelOption[] = [ - { label: 'Whisper Tiny', value: WHISPER_TINY_EN }, - { label: 'Whisper Tiny Q', value: WHISPER_TINY_EN_QUANTIZED }, - { label: 'Whisper Base', value: WHISPER_BASE_EN }, - { label: 'Whisper Small', value: WHISPER_SMALL_EN }, + { + label: 'Whisper Tiny', + value: speechToText.whisper_tiny_en({ quant: false }), + }, + { + label: 'Whisper Tiny Q', + value: speechToText.whisper_tiny_en(), + }, + { + label: 'Whisper Base', + value: speechToText.whisper_base_en(), + }, + { + label: 'Whisper Small', + value: speechToText.whisper_small_en(), + }, ]; import FontAwesome from '@expo/vector-icons/FontAwesome'; import { @@ -46,8 +56,9 @@ import ErrorBanner from '../components/ErrorBanner'; const isSimulator = DeviceInfo.isEmulatorSync(); export const SpeechToTextScreen = ({ onBack }: { onBack: () => void }) => { - const [selectedModel, setSelectedModel] = - useState(WHISPER_TINY_EN); + const [selectedModel, setSelectedModel] = useState( + speechToText.whisper_tiny_en({ quant: false }) + ); const model = useSpeechToText({ model: selectedModel, diff --git a/apps/text-embeddings/app/clip-embeddings/index.tsx b/apps/text-embeddings/app/clip-embeddings/index.tsx index c88220eb4f..2f37dffecd 100644 --- a/apps/text-embeddings/app/clip-embeddings/index.tsx +++ b/apps/text-embeddings/app/clip-embeddings/index.tsx @@ -13,19 +13,25 @@ import { } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { + models, useTextEmbeddings, useImageEmbeddings, - CLIP_VIT_BASE_PATCH32_TEXT, - CLIP_VIT_BASE_PATCH32_IMAGE, - CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED, ImageEmbeddingsProps, } from 'react-native-executorch'; type ImageEmbeddingModel = ImageEmbeddingsProps['model']; const IMAGE_MODELS: { label: string; value: ImageEmbeddingModel }[] = [ - { label: 'ViT-B/32 Quantized', value: CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED }, - { label: 'ViT-B/32 FP32', value: CLIP_VIT_BASE_PATCH32_IMAGE }, + { + label: 'ViT-B/32 Quantized', + value: models.image_embedding.clip_vit_base_patch32_image(), + }, + { + label: 'ViT-B/32 FP32', + value: models.image_embedding.clip_vit_base_patch32_image({ + quant: false, + }), + }, ]; import { launchImageLibrary } from 'react-native-image-picker'; import { useIsFocused } from '@react-navigation/native'; @@ -48,9 +54,13 @@ export default function ClipEmbeddingsScreenWrapper() { function ClipEmbeddingsScreen() { const [selectedImageModel, setSelectedImageModel] = - useState(CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED); + useState( + models.image_embedding.clip_vit_base_patch32_image() + ); - const textModel = useTextEmbeddings({ model: CLIP_VIT_BASE_PATCH32_TEXT }); + const textModel = useTextEmbeddings({ + model: models.text_embedding.clip_vit_base_patch32_text(), + }); const imageModel = useImageEmbeddings({ model: selectedImageModel }); const [imageUri, setImageUri] = useState(null); diff --git a/apps/text-embeddings/app/text-embeddings/index.tsx b/apps/text-embeddings/app/text-embeddings/index.tsx index 492cdf48b1..5120688edb 100644 --- a/apps/text-embeddings/app/text-embeddings/index.tsx +++ b/apps/text-embeddings/app/text-embeddings/index.tsx @@ -13,35 +13,43 @@ import { import { Ionicons } from '@expo/vector-icons'; import { ModelPicker } from '../../components/ModelPicker'; import { + models, useTextEmbeddings, - ALL_MINILM_L6_V2, - ALL_MPNET_BASE_V2, - MULTI_QA_MINILM_L6_COS_V1, - MULTI_QA_MPNET_BASE_DOT_V1, - DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W, - DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML, - PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED, TextEmbeddingsProps, } from 'react-native-executorch'; +const textEmbedding = models.text_embedding; type TextEmbeddingModel = TextEmbeddingsProps['model']; const MODELS: { label: string; value: TextEmbeddingModel }[] = [ - { label: 'MiniLM L6', value: ALL_MINILM_L6_V2 }, - { label: 'MPNet Base', value: ALL_MPNET_BASE_V2 }, - { label: 'MultiQA MiniLM', value: MULTI_QA_MINILM_L6_COS_V1 }, - { label: 'MultiQA MPNet', value: MULTI_QA_MPNET_BASE_DOT_V1 }, + { label: 'MiniLM L6', value: textEmbedding.all_minilm_l6_v2() }, { - label: 'Multilingual DistilUSE (8da4w)', - value: DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W, + label: 'MPNet Base', + value: textEmbedding.all_mpnet_base_v2(), + }, + { + label: 'MultiQA MiniLM', + value: textEmbedding.multi_qa_minilm_l6_cos_v1(), + }, + { + label: 'MultiQA MPNet', + value: textEmbedding.multi_qa_mpnet_base_dot_v1(), + }, + { + label: 'Multilingual DistilUSE (xnnpack)', + value: textEmbedding.distiluse_base_multilingual_cased_v2({ + backend: 'xnnpack', + }), }, { label: 'Multilingual DistilUSE (CoreML)', - value: DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML, + value: textEmbedding.distiluse_base_multilingual_cased_v2({ + backend: 'coreml', + }), }, { label: 'Multilingual Paraphrase (8da4w)', - value: PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED, + value: textEmbedding.paraphrase_multilingual_minilm_l12_v2(), }, ]; import { useIsFocused } from '@react-navigation/native'; @@ -55,8 +63,9 @@ export default function TextEmbeddingsScreenWrapper() { } function TextEmbeddingsScreen() { - const [selectedModel, setSelectedModel] = - useState(ALL_MINILM_L6_V2); + const [selectedModel, setSelectedModel] = useState( + textEmbedding.all_minilm_l6_v2() + ); const model = useTextEmbeddings({ model: selectedModel }); const [error, setError] = useState(null); diff --git a/docs/docs/05-utilities/model-registry.md b/docs/docs/05-utilities/model-registry.md index 02a74bbb13..586d32e91e 100644 --- a/docs/docs/05-utilities/model-registry.md +++ b/docs/docs/05-utilities/model-registry.md @@ -2,36 +2,140 @@ title: Model Registry --- -The [Model Registry](/react-native-executorch/docs/next/api-reference/variables/MODEL_REGISTRY) is a collection of all pre-configured model definitions shipped with React Native ExecuTorch. Each entry contains the model's name and all source URLs needed to download and run it, so you don't have to manage URLs manually. +The Model Registry is a typed, grouped index of every model shipped with React Native ExecuTorch. It removes the need to memorize per-model constant names: pick a capability group, pick a model, and optionally opt out of quantization or override the backend. -## Usage +```typescript +import { models } from 'react-native-executorch'; + +// Default (quantized when available, platform-default backend). +const llm = useLLM({ model: models.llm.llama3_2_3b() }); + +// Non-quantized variant. +const llmBase = useLLM({ model: models.llm.llama3_2_3b({ quant: false }) }); +``` + +Each leaf is a **function**. Call it (optionally with `{ quant, backend }`) to get the resolved model config. Accessors are not readable as values — this avoids a class of React state pitfalls (`useState` lazy-init, `useMemo`/`useCallback` deps), and pickers can fall back to plain `===` reference equality on the returned config. + +## Shape + +`models` is grouped by capability. Each leaf is a callable accessor; voices (for `text_to_speech`) are plain objects. + +| Group | Examples | +| ----------------------- | ----------------------------------------------------------------------------------------------------------- | +| `llm` | `llama3_2_3b`, `qwen3_4b`, `smollm2_1_1_7b`, `phi_4_mini_4b`, `bielik_v3_0_1_5b`, `lfm2_5_1_2b_instruct`, … | +| `multimodal` | `lfm2_5_vl_1_6b`, `lfm2_5_vl_450m` | +| `classification` | `efficientnet_v2_s`, `privacy_filter_openai`, `privacy_filter_nemotron` | +| `object_detection` | `ssdlite_320_mobilenet_v3_large`, `yolo26n` … `yolo26x`, `rf_detr_nano`, `fastsam_s`, `fastsam_x` | +| `semantic_segmentation` | `deeplab_v3_resnet50`, `lraspp_mobilenet_v3_large`, `fcn_resnet101`, `selfie_segmentation`, … | +| `instance_segmentation` | `yolo26n_seg` … `yolo26x_seg`, `rf_detr_nano_seg` | +| `style_transfer` | `candy`, `mosaic`, `rain_princess`, `udnie` | +| `speech_to_text` | `whisper_tiny_en`, `whisper_base`, `whisper_small_en`, … | +| `text_to_speech` | `kokoro_small`, `kokoro_medium`, `voices.{af_heart, af_river, af_sarah, am_adam, …}` | +| `text_embedding` | `all_minilm_l6_v2`, `all_mpnet_base_v2`, `clip_vit_base_patch32_text`, … | +| `image_embedding` | `clip_vit_base_patch32_image` | +| `image_generation` | `bk_sdm_tiny_vpred_256`, `bk_sdm_tiny_vpred_512` | +| `vad` | `fsmn_vad` | +| `ocr` _(parameterized)_ | `models.ocr({ language: 'en' })` — see [§OCR](#ocr) below | + +## Options ```typescript -import { MODEL_REGISTRY, LFM2_5_1_2B_INSTRUCT } from 'react-native-executorch'; +type ModelOpts = { + quant?: boolean; // Pick the non-quantized variant when false. Defaults to the quantized variant when one is published. + backend?: B; // Explicit backend; the set of allowed values is per-model. +}; ``` -### Accessing a model directly +- `quant` defaults to the quantized variant for models that publish one (e.g. `llama3_2_3b` → SpinQuant, `efficientnet_v2_s` → int8). Pass `{ quant: false }` to get the full-precision variant. For models with a single variant, `quant` is accepted but has no effect. +- `backend` selects an explicit backend. The accessor's call signature is typed to exactly the backends the model ships with, so requesting one the model doesn't publish is a compile-time error (e.g. `models.llm.llama3_2_3b({ backend: 'coreml' })` does not type-check — Llama 3.2 is xnnpack-only). When `backend` is omitted, the platform-default applies (typically CoreML on iOS and XNNPACK on Android for multi-backend models). + +## Usage patterns -Every model config is exported as a standalone constant: +### Default model ```typescript -import { LFM2_5_1_2B_INSTRUCT } from 'react-native-executorch'; +import { models } from 'react-native-executorch'; -const llm = useLLM({ model: LFM2_5_1_2B_INSTRUCT }); +const llm = useLLM({ model: models.llm.llama3_2_3b() }); +const classifier = useClassification({ + model: models.classification.efficientnet_v2_s(), +}); +const stt = useSpeechToText({ + model: models.speech_to_text.whisper_tiny_en(), +}); ``` -### Listing all models +### Non-quantized variant -Use `MODEL_REGISTRY` to discover and enumerate all available models: +```typescript +const llm = useLLM({ model: models.llm.qwen3_4b({ quant: false }) }); +const classifier = useClassification({ + model: models.classification.efficientnet_v2_s({ quant: false }), +}); +``` + +### Explicit backend ```typescript -import { MODEL_REGISTRY } from 'react-native-executorch'; +// Force XNNPACK on iOS (overrides the CoreML default). +const detector = useObjectDetection({ + model: models.object_detection.rf_detr_nano({ backend: 'xnnpack' }), +}); + +// Combine `quant` and `backend`. +const styled = useStyleTransfer({ + model: models.style_transfer.candy({ backend: 'coreml', quant: false }), +}); +``` -// Get all model names -const names = Object.values(MODEL_REGISTRY.ALL_MODELS).map((m) => m.modelName); +### Text-to-speech -// Find models by name -const whisperModels = Object.values(MODEL_REGISTRY.ALL_MODELS).filter((m) => - m.modelName.includes('whisper') -); +`text_to_speech` models pair with a voice. Voices have no quant/backend axis and are exposed as plain configs under `voices`. + +```typescript +import { models } from 'react-native-executorch'; + +const tts = useTextToSpeech({ + model: models.text_to_speech.kokoro_small(), + voice: models.text_to_speech.voices.af_heart, +}); ``` + +### OCR + +OCR is parameterized by language. The accessor builds the right detector + per-alphabet recognizer combo for the requested ISO language token: + +```typescript +const ocr = useOcr({ + model: models.ocr({ language: 'en' }), +}); +``` + +The `language` parameter is type-narrowed to supported tokens (`'en'`, `'es'`, `'ja'`, `'ko'`, …). See the OCR docs for the full list. + +### Direct imports still work + +Every model is also exported as a top-level constant. Either style is supported: + +```typescript +import { LFM2_5_1_2B_INSTRUCT, models } from 'react-native-executorch'; + +useLLM({ model: LFM2_5_1_2B_INSTRUCT }); +useLLM({ model: models.llm.lfm2_5_1_2b_instruct() }); +``` + +## Migration from the previous registry + +Earlier releases exposed `MODEL_REGISTRY` as an uppercase, dual-value/function shape. That has been replaced with a function-only, lowercase `models` export. + +```typescript +// Before +useLLM(MODEL_REGISTRY.LLM.LLAMA3_2_3B); +useLLM(MODEL_REGISTRY.LLM.LLAMA3_2_3B({ quant: false })); + +// After +useLLM({ model: models.llm.llama3_2_3b() }); +useLLM({ model: models.llm.llama3_2_3b({ quant: false }) }); +``` + +Individual constant imports (`LLAMA3_2_3B`, `WHISPER_TINY_EN`, …) are unchanged. diff --git a/docs/versioned_docs/version-0.8.x/05-utilities/model-registry.md b/docs/versioned_docs/version-0.8.x/05-utilities/model-registry.md index 3b4241c986..7c15dc1205 100644 --- a/docs/versioned_docs/version-0.8.x/05-utilities/model-registry.md +++ b/docs/versioned_docs/version-0.8.x/05-utilities/model-registry.md @@ -2,7 +2,7 @@ title: Model Registry --- -The [Model Registry](/react-native-executorch/docs/next/api-reference/variables/MODEL_REGISTRY) is a collection of all pre-configured model definitions shipped with React Native ExecuTorch. Each entry contains the model's name and all source URLs needed to download and run it, so you don't have to manage URLs manually. +The [Model Registry](../api-reference/variables/MODEL_REGISTRY) is a collection of all pre-configured model definitions shipped with React Native ExecuTorch. Each entry contains the model's name and all source URLs needed to download and run it, so you don't have to manage URLs manually. ## Usage diff --git a/packages/react-native-executorch/src/constants/modelRegistry.ts b/packages/react-native-executorch/src/constants/modelRegistry.ts new file mode 100644 index 0000000000..1215e96b03 --- /dev/null +++ b/packages/react-native-executorch/src/constants/modelRegistry.ts @@ -0,0 +1,514 @@ +import { Platform } from 'react-native'; +import * as M from './modelUrls'; +import * as OCR from './ocr/models'; +import { symbols } from './ocr/symbols'; +import { KOKORO_SMALL, KOKORO_MEDIUM } from './tts/models'; +import { + KOKORO_VOICE_AF_HEART, + KOKORO_VOICE_AF_RIVER, + KOKORO_VOICE_AF_SARAH, + KOKORO_VOICE_AM_ADAM, + KOKORO_VOICE_AM_MICHAEL, + KOKORO_VOICE_AM_SANTA, + KOKORO_VOICE_BF_EMMA, + KOKORO_VOICE_BM_DANIEL, +} from './tts/voices'; + +/** + * Backend options accepted by `models` accessors. + * + * The set of backends a particular model can be loaded with is encoded in + * its accessor's call signature — e.g. `models.llm.llama3_2_3b` only accepts + * `'xnnpack'`, while `models.object_detection.rf_detr_nano` accepts + * `'xnnpack' | 'coreml'`. Passing a backend a model doesn't ship is a + * compile-time error. + * @category Utils + */ +export type Backend = 'xnnpack' | 'coreml' | 'vulkan' | 'qnn'; + +/** + * Options for a `models` accessor call. + * @typeParam B - Subset of {@link Backend} that the accessor actually supports. + * @category Utils + */ +export type ModelOpts = { + /** Pick the non-quantized variant when `false`. Defaults to the quantized variant when one is published. */ + quant?: boolean; + /** Explicit backend; defaults to the platform-preferred backend for the model. */ + backend?: B; +}; + +// Accessors are functions; calling with no opts returns the platform default. +type Accessor = ( + opts?: ModelOpts +) => C; + +type BackendCell = { + base?: { modelName: string }; + quant?: { modelName: string }; +}; +type AnyVariantMap = Partial>; +type PlatformDefaults = { + ios?: B; + android?: B; + /** Fallback when no platform-specific default is set. */ + default?: B; +}; + +type CellConfig = T extends { base?: infer D; quant?: infer Q } + ? NonNullable | NonNullable + : never; +type ConfigOf = Extract< + { [K in keyof V]: CellConfig }[keyof V], + { modelName: string } +>; +type BackendsOf = Extract; + +const BACKEND_ORDER: Backend[] = ['xnnpack', 'coreml', 'vulkan', 'qnn']; + +function firstBackend(variants: AnyVariantMap): Backend { + for (const b of BACKEND_ORDER) { + if (variants[b]) return b; + } + throw new Error('Model variant map is empty.'); +} + +function resolveBackend( + variants: AnyVariantMap, + platformDefaults: PlatformDefaults | undefined, + requested: Backend | undefined +): Backend { + if (requested) return requested; + if (platformDefaults) { + if (Platform.OS === 'ios' && platformDefaults.ios) + return platformDefaults.ios; + if (Platform.OS === 'android' && platformDefaults.android) { + return platformDefaults.android; + } + if (platformDefaults.default) return platformDefaults.default; + } + return firstBackend(variants); +} + +function resolveCell(cell: BackendCell, quant: boolean): { modelName: string } { + // Fall back to the other slot when the requested precision is missing, + // so single-precision backends still work either way. + const primary = quant ? cell.quant : cell.base; + const fallback = quant ? cell.base : cell.quant; + const result = primary ?? fallback; + if (!result) { + throw new Error('Model variant cell has no config.'); + } + return result; +} + +function resolveVariant( + variants: AnyVariantMap, + platformDefaults: PlatformDefaults | undefined, + opts: ModelOpts +): { modelName: string } { + const backend = resolveBackend(variants, platformDefaults, opts.backend); + const cell = variants[backend]; + if (!cell) { + throw new Error(`Backend '${backend}' is not available for this model.`); + } + return resolveCell(cell, opts.quant !== false); +} + +// Build an Accessor from a per-backend variant map and an optional +// platform-default policy. The resulting accessor's `backend` parameter is +// typed to exactly the keys present in `variants`. +function variant( + variants: V, + platformDefaults?: PlatformDefaults> +): Accessor, BackendsOf> { + type C = ConfigOf; + type B = BackendsOf; + return (opts: ModelOpts = {}) => + resolveVariant(variants, platformDefaults, opts) as C; +} + +// Single-config accessor (xnnpack-only, no quantized variant). +function base(c: C) { + return variant({ xnnpack: { base: c } }); +} + +// xnnpack-only accessor with a `base` / `quant` pair. +function pair( + baseC: D, + quantC: Q +) { + return variant({ xnnpack: { base: baseC, quant: quantC } }); +} + +// ───────────────────────────────────────────────────────────────────────────── +// Per-backend variant maps for models that ship more than one backend. +// ───────────────────────────────────────────────────────────────────────────── + +const EFFICIENTNET_V2_S_VARIANTS = { + xnnpack: { + base: { + modelName: 'efficientnet-v2-s' as const, + modelSource: M.EFFICIENTNET_V2_S_XNNPACK_FP32_MODEL, + }, + quant: { + modelName: 'efficientnet-v2-s-quantized' as const, + modelSource: M.EFFICIENTNET_V2_S_XNNPACK_INT8_MODEL, + }, + }, + coreml: { + base: { + modelName: 'efficientnet-v2-s' as const, + modelSource: M.EFFICIENTNET_V2_S_COREML_FP32_MODEL, + }, + quant: { + modelName: 'efficientnet-v2-s-quantized' as const, + modelSource: M.EFFICIENTNET_V2_S_COREML_FP16_MODEL, + }, + }, +}; + +const SSDLITE_320_MOBILENET_V3_LARGE_VARIANTS = { + xnnpack: { + base: { + modelName: 'ssdlite-320-mobilenet-v3-large' as const, + modelSource: M.SSDLITE_320_MOBILENET_V3_LARGE_XNNPACK_FP32_MODEL, + }, + }, + coreml: { + base: { + modelName: 'ssdlite-320-mobilenet-v3-large' as const, + modelSource: M.SSDLITE_320_MOBILENET_V3_LARGE_COREML_FP16_MODEL, + }, + }, +}; + +const RF_DETR_NANO_VARIANTS = { + xnnpack: { + base: { + modelName: 'rf-detr-nano' as const, + modelSource: M.RF_DETR_NANO_XNNPACK_FP32_MODEL, + }, + }, + coreml: { + base: { + modelName: 'rf-detr-nano' as const, + modelSource: M.RF_DETR_NANO_COREML_INT8_MODEL, + }, + }, +}; + +const RF_DETR_NANO_SEG_VARIANTS = { + xnnpack: { + base: { + modelName: 'rfdetr-nano-seg' as const, + modelSource: M.RF_DETR_NANO_SEG_XNNPACK_FP32_MODEL, + }, + }, + coreml: { + base: { + modelName: 'rfdetr-nano-seg' as const, + modelSource: M.RF_DETR_NANO_SEG_COREML_INT8_MODEL, + }, + }, +}; + +const FASTSAM_S_VARIANTS = { + xnnpack: { + base: { + modelName: 'fastsam-s' as const, + modelSource: M.FASTSAM_S_XNNPACK_FP32_MODEL, + }, + }, + coreml: { + base: { + modelName: 'fastsam-s' as const, + modelSource: M.FASTSAM_S_COREML_FP16_MODEL, + }, + }, +}; + +const FASTSAM_X_VARIANTS = { + xnnpack: { + base: { + modelName: 'fastsam-x' as const, + modelSource: M.FASTSAM_X_XNNPACK_FP32_MODEL, + }, + }, + coreml: { + base: { + modelName: 'fastsam-x' as const, + modelSource: M.FASTSAM_X_COREML_FP16_MODEL, + }, + }, +}; + +function styleTransferVariants< + const Display extends string, + const Slug extends string, +>(display: Display, slug: Slug) { + const urls = M.styleTransferUrls(display, slug); + return { + xnnpack: { + base: { + modelName: `style-transfer-${display}`, + modelSource: urls.xnnpackBase, + } as { + modelName: `style-transfer-${Display}`; + modelSource: string; + }, + quant: { + modelName: `style-transfer-${display}-quantized`, + modelSource: urls.xnnpackQuant, + } as { + modelName: `style-transfer-${Display}-quantized`; + modelSource: string; + }, + }, + coreml: { + base: { + modelName: `style-transfer-${display}`, + modelSource: urls.coremlBase, + } as { + modelName: `style-transfer-${Display}`; + modelSource: string; + }, + quant: { + modelName: `style-transfer-${display}-quantized`, + modelSource: urls.coremlQuant, + } as { + modelName: `style-transfer-${Display}-quantized`; + modelSource: string; + }, + }, + }; +} + +const STYLE_TRANSFER_CANDY_VARIANTS = styleTransferVariants('candy', 'candy'); +const STYLE_TRANSFER_MOSAIC_VARIANTS = styleTransferVariants( + 'mosaic', + 'mosaic' +); +const STYLE_TRANSFER_RAIN_PRINCESS_VARIANTS = styleTransferVariants( + 'rain-princess', + 'rain_princess' +); +const STYLE_TRANSFER_UDNIE_VARIANTS = styleTransferVariants('udnie', 'udnie'); + +const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_VARIANTS = { + xnnpack: { + base: { + modelName: 'distiluse-base-multilingual-cased-v2-8da4w' as const, + modelSource: M.DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W_MODEL, + tokenizerSource: M.DISTILUSE_BASE_MULTILINGUAL_CASED_V2_TOKENIZER, + }, + }, + coreml: { + base: { + modelName: 'distiluse-base-multilingual-cased-v2-coreml' as const, + modelSource: M.DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML_MODEL, + tokenizerSource: M.DISTILUSE_BASE_MULTILINGUAL_CASED_V2_TOKENIZER, + }, + }, +}; + +const COREML_ON_IOS = { ios: 'coreml', default: 'xnnpack' } as const; + +// ───────────────────────────────────────────────────────────────────────────── +// OCR — language-parameterized accessor. +// +// The OCR pipeline ships one CRAFT detector + per-alphabet CRNN recognizers, +// already paired up in `OCR_` objects keyed by ISO language token +// (the `.language` field on each export). Build a runtime map from those +// exports so the user only needs to pass `{ language: 'en' }`. +// ───────────────────────────────────────────────────────────────────────────── + +type OcrConfig = typeof OCR.OCR_ABAZA; +type SupportedLanguage = keyof typeof symbols; + +const OCR_BY_LANGUAGE: Partial> = (() => { + const map: Partial> = {}; + for (const value of Object.values(OCR) as OcrConfig[]) { + if (value && typeof value === 'object' && 'language' in value) { + map[value.language as SupportedLanguage] = value; + } + } + return map; +})(); + +function ocr({ language }: { language: SupportedLanguage }): OcrConfig { + const cfg = OCR_BY_LANGUAGE[language]; + if (!cfg) { + throw new Error( + `OCR is not published for language '${language}'. ` + + `Supported: ${Object.keys(OCR_BY_LANGUAGE).sort().join(', ')}` + ); + } + return cfg; +} + +/** + * Typed model registry grouped by capability. Each entry is a function-only + * accessor: call it (optionally with `{ quant, backend }`) to get the resolved + * config. The `backend` parameter is typed to exactly the backends a given + * model ships with — asking for a backend a model doesn't publish is a + * compile-time error. + * @example + * ```ts + * import { models } from 'react-native-executorch'; + * + * // Platform default (CoreML on iOS, XNNPACK on Android for multi-backend models). + * useObjectDetection({ model: models.object_detection.rf_detr_nano() }); + * + * // Explicit backend. + * useObjectDetection({ + * model: models.object_detection.rf_detr_nano({ backend: 'xnnpack' }), + * }); + * + * // Non-quantized variant. + * useLLM({ model: models.llm.llama3_2_3b({ quant: false }) }); + * + * // OCR — language-parameterized. + * useOcr({ model: models.ocr({ language: 'en' }) }); + * ``` + * @category Utils + */ +export const models = { + llm: { + llama3_2_1b: pair(M.LLAMA3_2_1B, M.LLAMA3_2_1B_SPINQUANT), + llama3_2_3b: pair(M.LLAMA3_2_3B, M.LLAMA3_2_3B_SPINQUANT), + qwen3_0_6b: pair(M.QWEN3_0_6B, M.QWEN3_0_6B_QUANTIZED), + qwen3_1_7b: pair(M.QWEN3_1_7B, M.QWEN3_1_7B_QUANTIZED), + qwen3_4b: pair(M.QWEN3_4B, M.QWEN3_4B_QUANTIZED), + qwen3_5_0_8b: base(M.QWEN3_5_0_8B_QUANTIZED), + qwen3_5_2b: base(M.QWEN3_5_2B_QUANTIZED), + qwen2_5_0_5b: pair(M.QWEN2_5_0_5B, M.QWEN2_5_0_5B_QUANTIZED), + qwen2_5_1_5b: pair(M.QWEN2_5_1_5B, M.QWEN2_5_1_5B_QUANTIZED), + qwen2_5_3b: pair(M.QWEN2_5_3B, M.QWEN2_5_3B_QUANTIZED), + hammer2_1_0_5b: pair(M.HAMMER2_1_0_5B, M.HAMMER2_1_0_5B_QUANTIZED), + hammer2_1_1_5b: pair(M.HAMMER2_1_1_5B, M.HAMMER2_1_1_5B_QUANTIZED), + hammer2_1_3b: pair(M.HAMMER2_1_3B, M.HAMMER2_1_3B_QUANTIZED), + smollm2_1_135m: pair(M.SMOLLM2_1_135M, M.SMOLLM2_1_135M_QUANTIZED), + smollm2_1_360m: pair(M.SMOLLM2_1_360M, M.SMOLLM2_1_360M_QUANTIZED), + smollm2_1_1_7b: pair(M.SMOLLM2_1_1_7B, M.SMOLLM2_1_1_7B_QUANTIZED), + phi_4_mini_4b: pair(M.PHI_4_MINI_4B, M.PHI_4_MINI_4B_QUANTIZED), + lfm2_5_350m: pair(M.LFM2_5_350M, M.LFM2_5_350M_QUANTIZED), + lfm2_5_1_2b_instruct: pair( + M.LFM2_5_1_2B_INSTRUCT, + M.LFM2_5_1_2B_INSTRUCT_QUANTIZED + ), + bielik_v3_0_1_5b: pair(M.BIELIK_V3_0_1_5B, M.BIELIK_V3_0_1_5B_QUANTIZED), + }, + multimodal: { + lfm2_5_vl_1_6b: base(M.LFM2_5_VL_1_6B_QUANTIZED), + lfm2_5_vl_450m: base(M.LFM2_5_VL_450M_QUANTIZED), + }, + classification: { + efficientnet_v2_s: variant(EFFICIENTNET_V2_S_VARIANTS, COREML_ON_IOS), + privacy_filter_openai: base(M.PRIVACY_FILTER_OPENAI), + privacy_filter_nemotron: base(M.PRIVACY_FILTER_NEMOTRON), + }, + object_detection: { + ssdlite_320_mobilenet_v3_large: variant( + SSDLITE_320_MOBILENET_V3_LARGE_VARIANTS, + COREML_ON_IOS + ), + rf_detr_nano: variant(RF_DETR_NANO_VARIANTS, COREML_ON_IOS), + yolo26n: base(M.YOLO26N), + yolo26s: base(M.YOLO26S), + yolo26m: base(M.YOLO26M), + yolo26l: base(M.YOLO26L), + yolo26x: base(M.YOLO26X), + fastsam_s: variant(FASTSAM_S_VARIANTS, COREML_ON_IOS), + fastsam_x: variant(FASTSAM_X_VARIANTS, COREML_ON_IOS), + }, + semantic_segmentation: { + deeplab_v3_resnet50: pair( + M.DEEPLAB_V3_RESNET50, + M.DEEPLAB_V3_RESNET50_QUANTIZED + ), + deeplab_v3_resnet101: pair( + M.DEEPLAB_V3_RESNET101, + M.DEEPLAB_V3_RESNET101_QUANTIZED + ), + deeplab_v3_mobilenet_v3_large: pair( + M.DEEPLAB_V3_MOBILENET_V3_LARGE, + M.DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED + ), + lraspp_mobilenet_v3_large: pair( + M.LRASPP_MOBILENET_V3_LARGE, + M.LRASPP_MOBILENET_V3_LARGE_QUANTIZED + ), + fcn_resnet50: pair(M.FCN_RESNET50, M.FCN_RESNET50_QUANTIZED), + fcn_resnet101: pair(M.FCN_RESNET101, M.FCN_RESNET101_QUANTIZED), + selfie_segmentation: base(M.SELFIE_SEGMENTATION), + }, + instance_segmentation: { + yolo26n_seg: base(M.YOLO26N_SEG), + yolo26s_seg: base(M.YOLO26S_SEG), + yolo26m_seg: base(M.YOLO26M_SEG), + yolo26l_seg: base(M.YOLO26L_SEG), + yolo26x_seg: base(M.YOLO26X_SEG), + rf_detr_nano_seg: variant(RF_DETR_NANO_SEG_VARIANTS, COREML_ON_IOS), + }, + style_transfer: { + candy: variant(STYLE_TRANSFER_CANDY_VARIANTS, COREML_ON_IOS), + mosaic: variant(STYLE_TRANSFER_MOSAIC_VARIANTS, COREML_ON_IOS), + rain_princess: variant( + STYLE_TRANSFER_RAIN_PRINCESS_VARIANTS, + COREML_ON_IOS + ), + udnie: variant(STYLE_TRANSFER_UDNIE_VARIANTS, COREML_ON_IOS), + }, + speech_to_text: { + whisper_tiny_en: pair(M.WHISPER_TINY_EN, M.WHISPER_TINY_EN_QUANTIZED), + whisper_base_en: pair(M.WHISPER_BASE_EN, M.WHISPER_BASE_EN_QUANTIZED), + whisper_small_en: pair(M.WHISPER_SMALL_EN, M.WHISPER_SMALL_EN_QUANTIZED), + whisper_tiny: base(M.WHISPER_TINY), + whisper_base: base(M.WHISPER_BASE), + whisper_small: base(M.WHISPER_SMALL), + }, + text_to_speech: { + kokoro_small: base(KOKORO_SMALL), + kokoro_medium: base(KOKORO_MEDIUM), + // Voices have no quant/backend axis; expose as plain configs. + voices: { + af_heart: KOKORO_VOICE_AF_HEART, + af_river: KOKORO_VOICE_AF_RIVER, + af_sarah: KOKORO_VOICE_AF_SARAH, + am_adam: KOKORO_VOICE_AM_ADAM, + am_michael: KOKORO_VOICE_AM_MICHAEL, + am_santa: KOKORO_VOICE_AM_SANTA, + bf_emma: KOKORO_VOICE_BF_EMMA, + bm_daniel: KOKORO_VOICE_BM_DANIEL, + }, + }, + text_embedding: { + all_minilm_l6_v2: base(M.ALL_MINILM_L6_V2), + all_mpnet_base_v2: base(M.ALL_MPNET_BASE_V2), + multi_qa_minilm_l6_cos_v1: base(M.MULTI_QA_MINILM_L6_COS_V1), + multi_qa_mpnet_base_dot_v1: base(M.MULTI_QA_MPNET_BASE_DOT_V1), + distiluse_base_multilingual_cased_v2: variant( + DISTILUSE_BASE_MULTILINGUAL_CASED_V2_VARIANTS, + COREML_ON_IOS + ), + paraphrase_multilingual_minilm_l12_v2: base( + M.PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED + ), + clip_vit_base_patch32_text: base(M.CLIP_VIT_BASE_PATCH32_TEXT), + }, + image_embedding: { + clip_vit_base_patch32_image: pair( + M.CLIP_VIT_BASE_PATCH32_IMAGE, + M.CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED + ), + }, + image_generation: { + bk_sdm_tiny_vpred_512: base(M.BK_SDM_TINY_VPRED_512), + bk_sdm_tiny_vpred_256: base(M.BK_SDM_TINY_VPRED_256), + }, + vad: { + fsmn_vad: base(M.FSMN_VAD), + }, + ocr, +} as const; diff --git a/packages/react-native-executorch/src/constants/modelUrls.ts b/packages/react-native-executorch/src/constants/modelUrls.ts index 159396add8..fde55814bc 100644 --- a/packages/react-native-executorch/src/constants/modelUrls.ts +++ b/packages/react-native-executorch/src/constants/modelUrls.ts @@ -3,19 +3,19 @@ import { PRIVACY_FILTER_NEMOTRON_LABELS, PRIVACY_FILTER_OPENAI_LABELS, } from './privacyFilterLabels'; -import { URL_PREFIX, PREVIOUS_VERSION_TAG, VERSION_TAG } from './versions'; +import { URL_PREFIX, VERSION_TAG, PREVIOUS_VERSION_TAG } from './versions'; // LLMs // LLAMA 3.2 -const LLAMA3_2_3B_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-3B/original/llama3_2_3B_bf16.pte`; +const LLAMA3_2_3B_MODEL = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/3b/xnnpack/llama_3_2_3b_xnnpack_bf16.pte`; const LLAMA3_2_3B_QLORA_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-3B/QLoRA/llama3_2-3B_qat_lora.pte`; -const LLAMA3_2_3B_SPINQUANT_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-3B/spinquant/llama3_2_3B_spinquant.pte`; -const LLAMA3_2_1B_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-1B/original/llama3_2_bf16.pte`; +const LLAMA3_2_3B_SPINQUANT_MODEL = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/3b/xnnpack/llama_3_2_3b_xnnpack_spinquant.pte`; +const LLAMA3_2_1B_MODEL = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/1b/xnnpack/llama_3_2_1b_xnnpack_bf16.pte`; const LLAMA3_2_1B_QLORA_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-1B/QLoRA/llama3_2_qat_lora.pte`; -const LLAMA3_2_1B_SPINQUANT_MODEL = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/llama-3.2-1B/spinquant/llama3_2_spinquant.pte`; -const LLAMA3_2_TOKENIZER = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const LLAMA3_2_TOKENIZER_CONFIG = `${URL_PREFIX}-llama-3.2/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const LLAMA3_2_1B_SPINQUANT_MODEL = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/1b/xnnpack/llama_3_2_1b_xnnpack_spinquant.pte`; +const LLAMA3_2_TOKENIZER = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/tokenizer.json`; +const LLAMA3_2_TOKENIZER_CONFIG = `${URL_PREFIX}-llama-3.2/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -28,6 +28,10 @@ export const LLAMA3_2_3B = { } as const; /** + * @deprecated Use `LLAMA3_2_3B_SPINQUANT` instead — SpinQuant is the + * canonical quantized Llama 3.2 3B variant going forward. This alias + * still resolves the v0.8.0 file for back-compat and will be removed in + * a future major release. * @category Models - LLM */ export const LLAMA3_2_3B_QLORA = { @@ -58,6 +62,10 @@ export const LLAMA3_2_1B = { } as const; /** + * @deprecated Use `LLAMA3_2_1B_SPINQUANT` instead — SpinQuant is the + * canonical quantized Llama 3.2 1B variant going forward. This alias + * still resolves the v0.8.0 file for back-compat and will be removed in + * a future major release. * @category Models - LLM */ export const LLAMA3_2_1B_QLORA = { @@ -78,14 +86,14 @@ export const LLAMA3_2_1B_SPINQUANT = { } as const; // QWEN 3 -const QWEN3_0_6B_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-0.6B/original/qwen3_0_6b_bf16.pte`; -const QWEN3_0_6B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-0.6B/quantized/qwen3_0_6b_8da4w.pte`; -const QWEN3_1_7B_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-1.7B/original/qwen3_1_7b_bf16.pte`; -const QWEN3_1_7B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-1.7B/quantized/qwen3_1_7b_8da4w.pte`; -const QWEN3_4B_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-4B/original/qwen3_4b_bf16.pte`; -const QWEN3_4B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/qwen-3-4B/quantized/qwen3_4b_8da4w.pte`; -const QWEN3_TOKENIZER = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const QWEN3_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const QWEN3_0_6B_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/0_6b/xnnpack/qwen_3_0_6b_xnnpack_bf16.pte`; +const QWEN3_0_6B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/0_6b/xnnpack/qwen_3_0_6b_xnnpack_8da4w.pte`; +const QWEN3_1_7B_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/1_7b/xnnpack/qwen_3_1_7b_xnnpack_bf16.pte`; +const QWEN3_1_7B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/1_7b/xnnpack/qwen_3_1_7b_xnnpack_8da4w.pte`; +const QWEN3_4B_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/4b/xnnpack/qwen_3_4b_xnnpack_bf16.pte`; +const QWEN3_4B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/4b/xnnpack/qwen_3_4b_xnnpack_8da4w.pte`; +const QWEN3_TOKENIZER = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/tokenizer.json`; +const QWEN3_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3/${VERSION_TAG}/tokenizer_config.json`; // Qwen3's published generation_config.json recommends temperature=0.6 and // top_p=0.95. We propagate those to every Qwen3 preset so model quality is @@ -162,14 +170,14 @@ export const QWEN3_4B_QUANTIZED = { } as const; // HAMMER 2.1 -const HAMMER2_1_0_5B_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-0.5B/original/hammer2_1_0_5B_bf16.pte`; -const HAMMER2_1_0_5B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-0.5B/quantized/hammer2_1_0_5B_8da4w.pte`; -const HAMMER2_1_1_5B_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-1.5B/original/hammer2_1_1_5B_bf16.pte`; -const HAMMER2_1_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-1.5B/quantized/hammer2_1_1_5B_8da4w.pte`; -const HAMMER2_1_3B_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-3B/original/hammer2_1_3B_bf16.pte`; -const HAMMER2_1_3B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/hammer-2.1-3B/quantized/hammer2_1_3B_8da4w.pte`; -const HAMMER2_1_TOKENIZER = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const HAMMER2_1_TOKENIZER_CONFIG = `${URL_PREFIX}-hammer-2.1/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const HAMMER2_1_0_5B_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/0_5b/xnnpack/hammer_2_1_0_5b_xnnpack_bf16.pte`; +const HAMMER2_1_0_5B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/0_5b/xnnpack/hammer_2_1_0_5b_xnnpack_8da4w.pte`; +const HAMMER2_1_1_5B_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/1_5b/xnnpack/hammer_2_1_1_5b_xnnpack_bf16.pte`; +const HAMMER2_1_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/1_5b/xnnpack/hammer_2_1_1_5b_xnnpack_8da4w.pte`; +const HAMMER2_1_3B_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/3b/xnnpack/hammer_2_1_3b_xnnpack_bf16.pte`; +const HAMMER2_1_3B_QUANTIZED_MODEL = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/3b/xnnpack/hammer_2_1_3b_xnnpack_8da4w.pte`; +const HAMMER2_1_TOKENIZER = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/tokenizer.json`; +const HAMMER2_1_TOKENIZER_CONFIG = `${URL_PREFIX}-hammer-2.1/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -232,14 +240,14 @@ export const HAMMER2_1_3B_QUANTIZED = { } as const; // SMOLLM2 -const SMOLLM2_1_135M_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-135M/original/smolLm2_135M_bf16.pte`; -const SMOLLM2_1_135M_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-135M/quantized/smolLm2_135M_8da4w.pte`; -const SMOLLM2_1_360M_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-360M/original/smolLm2_360M_bf16.pte`; -const SMOLLM2_1_360M_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-360M/quantized/smolLm2_360M_8da4w.pte`; -const SMOLLM2_1_1_7B_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-1.7B/original/smolLm2_1_7B_bf16.pte`; -const SMOLLM2_1_1_7B_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/smolLm-2-1.7B/quantized/smolLm2_1_7B_8da4w.pte`; -const SMOLLM2_1_TOKENIZER = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const SMOLLM2_1_TOKENIZER_CONFIG = `${URL_PREFIX}-smolLm-2/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const SMOLLM2_1_135M_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/135m/xnnpack/smollm2_135m_xnnpack_bf16.pte`; +const SMOLLM2_1_135M_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/135m/xnnpack/smollm2_135m_xnnpack_8da4w.pte`; +const SMOLLM2_1_360M_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/360m/xnnpack/smollm2_360m_xnnpack_bf16.pte`; +const SMOLLM2_1_360M_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/360m/xnnpack/smollm2_360m_xnnpack_8da4w.pte`; +const SMOLLM2_1_1_7B_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/1_7b/xnnpack/smollm2_1_7b_xnnpack_bf16.pte`; +const SMOLLM2_1_1_7B_QUANTIZED_MODEL = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/1_7b/xnnpack/smollm2_1_7b_xnnpack_8da4w.pte`; +const SMOLLM2_1_TOKENIZER = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/tokenizer.json`; +const SMOLLM2_1_TOKENIZER_CONFIG = `${URL_PREFIX}-smolLm-2/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -302,14 +310,14 @@ export const SMOLLM2_1_1_7B_QUANTIZED = { } as const; // QWEN 2.5 -const QWEN2_5_0_5B_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-0.5B/original/qwen2_5_0_5b_bf16.pte`; -const QWEN2_5_0_5B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-0.5B/quantized/qwen2_5_0_5b_8da4w.pte`; -const QWEN2_5_1_5B_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-1.5B/original/qwen2_5_1_5b_bf16.pte`; -const QWEN2_5_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-1.5B/quantized/qwen2_5_1_5b_8da4w.pte`; -const QWEN2_5_3B_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-3B/original/qwen2_5_3b_bf16.pte`; -const QWEN2_5_3B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/qwen-2.5-3B/quantized/qwen2_5_3b_8da4w.pte`; -const QWEN2_5_TOKENIZER = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const QWEN2_5_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-2.5/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const QWEN2_5_0_5B_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/0_5b/xnnpack/qwen_2_5_0_5b_xnnpack_bf16.pte`; +const QWEN2_5_0_5B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/0_5b/xnnpack/qwen_2_5_0_5b_xnnpack_8da4w.pte`; +const QWEN2_5_1_5B_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/1_5b/xnnpack/qwen_2_5_1_5b_xnnpack_bf16.pte`; +const QWEN2_5_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/1_5b/xnnpack/qwen_2_5_1_5b_xnnpack_8da4w.pte`; +const QWEN2_5_3B_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/3b/xnnpack/qwen_2_5_3b_xnnpack_bf16.pte`; +const QWEN2_5_3B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/3b/xnnpack/qwen_2_5_3b_xnnpack_8da4w.pte`; +const QWEN2_5_TOKENIZER = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/tokenizer.json`; +const QWEN2_5_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-2.5/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -372,9 +380,9 @@ export const QWEN2_5_3B_QUANTIZED = { } as const; // QWEN3.5-0.8B -const QWEN3_5_0_8B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-0.8B/qwen3_5_0_8b_xnnpack_8da4w.pte`; -const QWEN3_5_0_8B_TOKENIZER = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-0.8B/tokenizer.json`; -const QWEN3_5_0_8B_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-0.8B/tokenizer_config.json`; +const QWEN3_5_0_8B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/0_8b/xnnpack/qwen_3_5_0_8b_xnnpack_8da4w.pte`; +const QWEN3_5_0_8B_TOKENIZER = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/0_8b/tokenizer.json`; +const QWEN3_5_0_8B_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/0_8b/tokenizer_config.json`; /** * @category Models - LLM @@ -387,9 +395,9 @@ export const QWEN3_5_0_8B_QUANTIZED = { } as const; // QWEN3.5-2B -const QWEN3_5_2B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-2B/qwen3_5_2b_xnnpack_8da4w.pte`; -const QWEN3_5_2B_TOKENIZER = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-2B/tokenizer.json`; -const QWEN3_5_2B_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/Qwen3.5-2B/tokenizer_config.json`; +const QWEN3_5_2B_QUANTIZED_MODEL = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/2b/xnnpack/qwen_3_5_2b_xnnpack_8da4w.pte`; +const QWEN3_5_2B_TOKENIZER = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/2b/tokenizer.json`; +const QWEN3_5_2B_TOKENIZER_CONFIG = `${URL_PREFIX}-qwen-3.5/${VERSION_TAG}/2b/tokenizer_config.json`; /** * @category Models - LLM @@ -402,10 +410,10 @@ export const QWEN3_5_2B_QUANTIZED = { } as const; // PHI 4 -const PHI_4_MINI_4B_MODEL = `${URL_PREFIX}-phi-4-mini/${PREVIOUS_VERSION_TAG}/original/phi-4-mini_bf16.pte`; -const PHI_4_MINI_4B_QUANTIZED_MODEL = `${URL_PREFIX}-phi-4-mini/${PREVIOUS_VERSION_TAG}/quantized/phi-4-mini_8da4w.pte`; -const PHI_4_MINI_TOKENIZER = `${URL_PREFIX}-phi-4-mini/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const PHI_4_MINI_TOKENIZER_CONFIG = `${URL_PREFIX}-phi-4-mini/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const PHI_4_MINI_4B_MODEL = `${URL_PREFIX}-phi-4-mini/${VERSION_TAG}/xnnpack/phi_4_mini_xnnpack_bf16.pte`; +const PHI_4_MINI_4B_QUANTIZED_MODEL = `${URL_PREFIX}-phi-4-mini/${VERSION_TAG}/xnnpack/phi_4_mini_xnnpack_8da4w.pte`; +const PHI_4_MINI_TOKENIZER = `${URL_PREFIX}-phi-4-mini/${VERSION_TAG}/tokenizer.json`; +const PHI_4_MINI_TOKENIZER_CONFIG = `${URL_PREFIX}-phi-4-mini/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -428,10 +436,10 @@ export const PHI_4_MINI_4B_QUANTIZED = { } as const; // LFM2.5-1.2B-Instruct -const LFM2_5_1_2B_INSTRUCT_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-1.2B-instruct/original/lfm2_5_1_2b_fp16.pte`; -const LFM2_5_1_2B_INSTRUCT_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-1.2B-instruct/quantized/lfm2_5_1_2b_8da4w.pte`; -const LFM2_5_1_2B_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-1.2B-instruct/tokenizer.json`; -const LFM2_5_1_2B_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-1.2B-instruct/tokenizer_config.json`; +const LFM2_5_1_2B_INSTRUCT_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/1_2b/xnnpack/lfm_2_5_1_2b_xnnpack_fp16.pte`; +const LFM2_5_1_2B_INSTRUCT_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/1_2b/xnnpack/lfm_2_5_1_2b_xnnpack_8da4w.pte`; +const LFM2_5_1_2B_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/1_2b/tokenizer.json`; +const LFM2_5_1_2B_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/1_2b/tokenizer_config.json`; /** * @category Models - LLM @@ -454,10 +462,10 @@ export const LFM2_5_1_2B_INSTRUCT_QUANTIZED = { } as const; // LFM2.5-350M -const LFM2_5_350M_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-350M/xnnpack/lfm2_5_350m_xnnpack_fp16.pte`; -const LFM2_5_350M_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-350M/xnnpack/lfm2_5_350m_xnnpack_8w4da.pte`; -const LFM2_5_350M_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-350M/tokenizer.json`; -const LFM2_5_350M_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-350M/tokenizer_config.json`; +const LFM2_5_350M_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/350m/xnnpack/lfm_2_5_350m_xnnpack_fp16.pte`; +const LFM2_5_350M_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/350m/xnnpack/lfm_2_5_350m_xnnpack_8da4w.pte`; +const LFM2_5_350M_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/350m/tokenizer.json`; +const LFM2_5_350M_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/350m/tokenizer_config.json`; /** * @category Models - LLM @@ -480,10 +488,10 @@ export const LFM2_5_350M_QUANTIZED = { } as const; // Bielik-v3.0 -const BIELIK_V3_0_1_5B_MODEL = `${URL_PREFIX}-bielik-v3.0/${PREVIOUS_VERSION_TAG}/bielik-v3.0-1.5B/original/bielik_1_5b_v3_0_instruct_xnnpack_fp16.pte`; -const BIELIK_V3_0_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-bielik-v3.0/${PREVIOUS_VERSION_TAG}/bielik-v3.0-1.5B/quantized/bielik_1_5b_v3_0_instruct_xnnpack_8da4w.pte`; -const BIELIK_V3_0_TOKENIZER = `${URL_PREFIX}-bielik-v3.0/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const BIELIK_V3_0_TOKENIZER_CONFIG = `${URL_PREFIX}-bielik-v3.0/${PREVIOUS_VERSION_TAG}/tokenizer_config.json`; +const BIELIK_V3_0_1_5B_MODEL = `${URL_PREFIX}-bielik-v3.0/${VERSION_TAG}/xnnpack/bielik_v3_0_1_5b_xnnpack_fp16.pte`; +const BIELIK_V3_0_1_5B_QUANTIZED_MODEL = `${URL_PREFIX}-bielik-v3.0/${VERSION_TAG}/xnnpack/bielik_v3_0_1_5b_xnnpack_8da4w.pte`; +const BIELIK_V3_0_TOKENIZER = `${URL_PREFIX}-bielik-v3.0/${VERSION_TAG}/tokenizer.json`; +const BIELIK_V3_0_TOKENIZER_CONFIG = `${URL_PREFIX}-bielik-v3.0/${VERSION_TAG}/tokenizer_config.json`; /** * @category Models - LLM @@ -506,14 +514,14 @@ export const BIELIK_V3_0_1_5B_QUANTIZED = { } as const; // LFM2.5-VL-1.6B -const LFM2_VL_1_6B_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-1.6B/quantized/lfm2_5_vl_1_6b_8da4w_xnnpack.pte`; -const LFM2_VL_1_6B_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-1.6B/tokenizer.json`; -const LFM2_VL_1_6B_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-1.6B/tokenizer_config.json`; +const LFM2_VL_1_6B_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_1_6b/xnnpack/lfm_2_5_vl_1_6b_xnnpack_8da4w.pte`; +const LFM2_VL_1_6B_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_1_6b/tokenizer.json`; +const LFM2_VL_1_6B_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_1_6b/tokenizer_config.json`; // LFM2.5-VL-450M -const LFM2_VL_450M_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-450M/lfm2_5_vl_450m_8da4w_xnnpack.pte`; -const LFM2_VL_450M_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-450M/tokenizer.json`; -const LFM2_VL_450M_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${PREVIOUS_VERSION_TAG}/lfm2.5-VL-450M/tokenizer_config.json`; +const LFM2_VL_450M_QUANTIZED_MODEL = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_450m/xnnpack/lfm_2_5_vl_450m_xnnpack_8da4w.pte`; +const LFM2_VL_450M_TOKENIZER = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_450m/tokenizer.json`; +const LFM2_VL_450M_TOKENIZER_CONFIG = `${URL_PREFIX}-lfm-2.5/${VERSION_TAG}/vl_450m/tokenizer_config.json`; /** * @category Models - VLM @@ -565,14 +573,18 @@ export const LFM2_VL_1_6B_QUANTIZED = LFM2_5_VL_1_6B_QUANTIZED; export const LFM2_VL_450M_QUANTIZED = LFM2_5_VL_450M_QUANTIZED; // Classification +export const EFFICIENTNET_V2_S_XNNPACK_FP32_MODEL = `${URL_PREFIX}-efficientnet-v2-s/${VERSION_TAG}/xnnpack/efficientnet_v2_s_xnnpack_fp32.pte`; +export const EFFICIENTNET_V2_S_XNNPACK_INT8_MODEL = `${URL_PREFIX}-efficientnet-v2-s/${VERSION_TAG}/xnnpack/efficientnet_v2_s_xnnpack_int8.pte`; +export const EFFICIENTNET_V2_S_COREML_FP32_MODEL = `${URL_PREFIX}-efficientnet-v2-s/${VERSION_TAG}/coreml/efficientnet_v2_s_coreml_fp32.pte`; +export const EFFICIENTNET_V2_S_COREML_FP16_MODEL = `${URL_PREFIX}-efficientnet-v2-s/${VERSION_TAG}/coreml/efficientnet_v2_s_coreml_fp16.pte`; const EFFICIENTNET_V2_S_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-efficientnet-v2-s/${PREVIOUS_VERSION_TAG}/coreml/efficientnet_v2_s_coreml_fp32.pte` - : `${URL_PREFIX}-efficientnet-v2-s/${PREVIOUS_VERSION_TAG}/xnnpack/efficientnet_v2_s_xnnpack_fp32.pte`; + ? EFFICIENTNET_V2_S_COREML_FP32_MODEL + : EFFICIENTNET_V2_S_XNNPACK_FP32_MODEL; const EFFICIENTNET_V2_S_QUANTIZED_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-efficientnet-v2-s/${PREVIOUS_VERSION_TAG}/coreml/efficientnet_v2_s_coreml_fp16.pte` - : `${URL_PREFIX}-efficientnet-v2-s/${PREVIOUS_VERSION_TAG}/xnnpack/efficientnet_v2_s_xnnpack_int8.pte`; + ? EFFICIENTNET_V2_S_COREML_FP16_MODEL + : EFFICIENTNET_V2_S_XNNPACK_INT8_MODEL; /** * @category Models - Classification @@ -591,14 +603,18 @@ export const EFFICIENTNET_V2_S_QUANTIZED = { } as const; // Object detection +export const SSDLITE_320_MOBILENET_V3_LARGE_XNNPACK_FP32_MODEL = `${URL_PREFIX}-ssdlite320-mobilenet-v3-large/${VERSION_TAG}/xnnpack/ssdlite320_mobilenet_v3_large_xnnpack_fp32.pte`; +export const SSDLITE_320_MOBILENET_V3_LARGE_COREML_FP16_MODEL = `${URL_PREFIX}-ssdlite320-mobilenet-v3-large/${VERSION_TAG}/coreml/ssdlite320_mobilenet_v3_large_coreml_fp16.pte`; +export const RF_DETR_NANO_XNNPACK_FP32_MODEL = `${URL_PREFIX}-rfdetr-nano-detector/${VERSION_TAG}/xnnpack/rfdetr_nano_xnnpack_fp32.pte`; +export const RF_DETR_NANO_COREML_INT8_MODEL = `${URL_PREFIX}-rfdetr-nano-detector/${VERSION_TAG}/coreml/rfdetr_nano_coreml_int8.pte`; const SSDLITE_320_MOBILENET_V3_LARGE_MODEL = Platform.OS === 'ios' - ? `${URL_PREFIX}-ssdlite320-mobilenet-v3-large/${PREVIOUS_VERSION_TAG}/coreml/ssdlite320_mobilenet_v3_large_coreml_fp16.pte` - : `${URL_PREFIX}-ssdlite320-mobilenet-v3-large/${PREVIOUS_VERSION_TAG}/xnnpack/ssdlite320_mobilenet_v3_large_xnnpack_fp32.pte`; + ? SSDLITE_320_MOBILENET_V3_LARGE_COREML_FP16_MODEL + : SSDLITE_320_MOBILENET_V3_LARGE_XNNPACK_FP32_MODEL; const RF_DETR_NANO_MODEL = Platform.OS === 'ios' - ? `${URL_PREFIX}-rfdetr-nano-detector/${PREVIOUS_VERSION_TAG}/coreml/rfdetr_n_det_coreml_int8.pte` - : `${URL_PREFIX}-rfdetr-nano-detector/${PREVIOUS_VERSION_TAG}/rfdetr_detector.pte`; + ? RF_DETR_NANO_COREML_INT8_MODEL + : RF_DETR_NANO_XNNPACK_FP32_MODEL; /** * @category Models - Object Detection @@ -617,11 +633,11 @@ export const RF_DETR_NANO = { } as const; // YOLO26 Object Detection -const YOLO26N_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${PREVIOUS_VERSION_TAG}/yolo26n/xnnpack/yolo26n.pte`; -const YOLO26S_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${PREVIOUS_VERSION_TAG}/yolo26s/xnnpack/yolo26s.pte`; -const YOLO26M_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${PREVIOUS_VERSION_TAG}/yolo26m/xnnpack/yolo26m.pte`; -const YOLO26L_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${PREVIOUS_VERSION_TAG}/yolo26l/xnnpack/yolo26l.pte`; -const YOLO26X_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${PREVIOUS_VERSION_TAG}/yolo26x/xnnpack/yolo26x.pte`; +const YOLO26N_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${VERSION_TAG}/n/xnnpack/yolo26_n_xnnpack_fp32.pte`; +const YOLO26S_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${VERSION_TAG}/s/xnnpack/yolo26_s_xnnpack_fp32.pte`; +const YOLO26M_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${VERSION_TAG}/m/xnnpack/yolo26_m_xnnpack_fp32.pte`; +const YOLO26L_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${VERSION_TAG}/l/xnnpack/yolo26_l_xnnpack_fp32.pte`; +const YOLO26X_DETECTION_MODEL = `${URL_PREFIX}-yolo26/${VERSION_TAG}/x/xnnpack/yolo26_x_xnnpack_fp32.pte`; /** * @category Models - Object Detection @@ -664,7 +680,7 @@ export const YOLO26X = { } as const; // YOLO26 Pose Estimation -const YOLO26N_POSE_MODEL = `${URL_PREFIX}-yolo26-pose/${VERSION_TAG}/yolo26n/xnnpack/yolo26n-pose_xnnpack.pte`; +const YOLO26N_POSE_MODEL = `${URL_PREFIX}-yolo26-pose/${VERSION_TAG}/xnnpack/yolo26_pose_n_xnnpack_fp32.pte`; /** * @category Models - Pose Estimation @@ -675,38 +691,64 @@ export const YOLO26N_POSE = { } as const; // Style transfer +/** + * Builds the four `(backend, precision)` URLs for a single style-transfer + * style. + * + * @param display - HF repo suffix (e.g. `rain-princess`). + * @param slug - .pte filename token (e.g. `rain_princess`). Differs from + * `display` for styles whose names contain spaces. + */ +export function styleTransferUrls< + const Display extends string, + const Slug extends string, +>(display: Display, slug: Slug) { + return { + xnnpackBase: `${URL_PREFIX}-style-transfer-${display}/${VERSION_TAG}/xnnpack/style_transfer_${slug}_xnnpack_fp32.pte`, + xnnpackQuant: `${URL_PREFIX}-style-transfer-${display}/${VERSION_TAG}/xnnpack/style_transfer_${slug}_xnnpack_int8.pte`, + coremlBase: `${URL_PREFIX}-style-transfer-${display}/${VERSION_TAG}/coreml/style_transfer_${slug}_coreml_fp32.pte`, + coremlQuant: `${URL_PREFIX}-style-transfer-${display}/${VERSION_TAG}/coreml/style_transfer_${slug}_coreml_fp16.pte`, + }; +} +const STYLE_TRANSFER_CANDY_URLS = styleTransferUrls('candy', 'candy'); +const STYLE_TRANSFER_MOSAIC_URLS = styleTransferUrls('mosaic', 'mosaic'); +const STYLE_TRANSFER_RAIN_PRINCESS_URLS = styleTransferUrls( + 'rain-princess', + 'rain_princess' +); +const STYLE_TRANSFER_UDNIE_URLS = styleTransferUrls('udnie', 'udnie'); const STYLE_TRANSFER_CANDY_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-candy/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_candy_coreml_fp32.pte` - : `${URL_PREFIX}-style-transfer-candy/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_candy_xnnpack_fp32.pte`; + ? STYLE_TRANSFER_CANDY_URLS.coremlBase + : STYLE_TRANSFER_CANDY_URLS.xnnpackBase; const STYLE_TRANSFER_CANDY_QUANTIZED_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-candy/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_candy_coreml_fp16.pte` - : `${URL_PREFIX}-style-transfer-candy/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_candy_xnnpack_int8.pte`; + ? STYLE_TRANSFER_CANDY_URLS.coremlQuant + : STYLE_TRANSFER_CANDY_URLS.xnnpackQuant; const STYLE_TRANSFER_MOSAIC_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-mosaic/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_mosaic_coreml_fp32.pte` - : `${URL_PREFIX}-style-transfer-mosaic/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_mosaic_xnnpack_fp32.pte`; + ? STYLE_TRANSFER_MOSAIC_URLS.coremlBase + : STYLE_TRANSFER_MOSAIC_URLS.xnnpackBase; const STYLE_TRANSFER_MOSAIC_QUANTIZED_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-mosaic/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_mosaic_coreml_fp16.pte` - : `${URL_PREFIX}-style-transfer-mosaic/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_mosaic_xnnpack_int8.pte`; + ? STYLE_TRANSFER_MOSAIC_URLS.coremlQuant + : STYLE_TRANSFER_MOSAIC_URLS.xnnpackQuant; const STYLE_TRANSFER_RAIN_PRINCESS_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-rain-princess/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_rain_princess_coreml_fp32.pte` - : `${URL_PREFIX}-style-transfer-rain-princess/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_rain_princess_xnnpack_fp32.pte`; + ? STYLE_TRANSFER_RAIN_PRINCESS_URLS.coremlBase + : STYLE_TRANSFER_RAIN_PRINCESS_URLS.xnnpackBase; const STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-rain-princess/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_rain_princess_coreml_fp16.pte` - : `${URL_PREFIX}-style-transfer-rain-princess/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_rain_princess_xnnpack_int8.pte`; + ? STYLE_TRANSFER_RAIN_PRINCESS_URLS.coremlQuant + : STYLE_TRANSFER_RAIN_PRINCESS_URLS.xnnpackQuant; const STYLE_TRANSFER_UDNIE_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-udnie/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_udnie_coreml_fp32.pte` - : `${URL_PREFIX}-style-transfer-udnie/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_udnie_xnnpack_fp32.pte`; + ? STYLE_TRANSFER_UDNIE_URLS.coremlBase + : STYLE_TRANSFER_UDNIE_URLS.xnnpackBase; const STYLE_TRANSFER_UDNIE_QUANTIZED_MODEL = Platform.OS === `ios` - ? `${URL_PREFIX}-style-transfer-udnie/${PREVIOUS_VERSION_TAG}/coreml/style_transfer_udnie_coreml_fp16.pte` - : `${URL_PREFIX}-style-transfer-udnie/${PREVIOUS_VERSION_TAG}/xnnpack/style_transfer_udnie_xnnpack_int8.pte`; + ? STYLE_TRANSFER_UDNIE_URLS.coremlQuant + : STYLE_TRANSFER_UDNIE_URLS.xnnpackQuant; /** * @category Models - Style Transfer @@ -773,32 +815,32 @@ export const STYLE_TRANSFER_UDNIE_QUANTIZED = { } as const; // S2T -const WHISPER_TINY_EN_TOKENIZER = `${URL_PREFIX}-whisper-tiny.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_TINY_EN_MODEL = `${URL_PREFIX}-whisper-tiny.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_tiny_en_xnnpack.pte`; +const WHISPER_TINY_EN_TOKENIZER = `${URL_PREFIX}-whisper-tiny.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_TINY_EN_MODEL = `${URL_PREFIX}-whisper-tiny.en/${VERSION_TAG}/xnnpack/whisper_tiny_en_xnnpack_fp32.pte`; -const WHISPER_TINY_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-tiny-quantized.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_TINY_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-tiny-quantized.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_tiny_en_quantized_xnnpack.pte`; +const WHISPER_TINY_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-tiny.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_TINY_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-tiny.en/${VERSION_TAG}/xnnpack/whisper_tiny_en_xnnpack_int8.pte`; -const WHISPER_BASE_EN_TOKENIZER = `${URL_PREFIX}-whisper-base.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_BASE_EN_MODEL = `${URL_PREFIX}-whisper-base.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_base_en_xnnpack.pte`; +const WHISPER_BASE_EN_TOKENIZER = `${URL_PREFIX}-whisper-base.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_BASE_EN_MODEL = `${URL_PREFIX}-whisper-base.en/${VERSION_TAG}/xnnpack/whisper_base_en_xnnpack_fp32.pte`; -const WHISPER_BASE_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-base-quantized.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_BASE_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-base-quantized.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_base_en_quantized_xnnpack.pte`; +const WHISPER_BASE_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-base.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_BASE_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-base.en/${VERSION_TAG}/xnnpack/whisper_base_en_xnnpack_int8.pte`; -const WHISPER_SMALL_EN_TOKENIZER = `${URL_PREFIX}-whisper-small.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_SMALL_EN_MODEL = `${URL_PREFIX}-whisper-small.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_small_en_xnnpack.pte`; +const WHISPER_SMALL_EN_TOKENIZER = `${URL_PREFIX}-whisper-small.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_SMALL_EN_MODEL = `${URL_PREFIX}-whisper-small.en/${VERSION_TAG}/xnnpack/whisper_small_en_xnnpack_fp32.pte`; -const WHISPER_SMALL_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-small-quantized.en/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_SMALL_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-small-quantized.en/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_small_en_quantized_xnnpack.pte`; +const WHISPER_SMALL_EN_QUANTIZED_TOKENIZER = `${URL_PREFIX}-whisper-small.en/${VERSION_TAG}/tokenizer.json`; +const WHISPER_SMALL_EN_QUANTIZED_MODEL = `${URL_PREFIX}-whisper-small.en/${VERSION_TAG}/xnnpack/whisper_small_en_xnnpack_int8.pte`; -const WHISPER_TINY_TOKENIZER = `${URL_PREFIX}-whisper-tiny/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_TINY_MODEL = `${URL_PREFIX}-whisper-tiny/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_tiny_xnnpack.pte`; +const WHISPER_TINY_TOKENIZER = `${URL_PREFIX}-whisper-tiny/${VERSION_TAG}/tokenizer.json`; +const WHISPER_TINY_MODEL = `${URL_PREFIX}-whisper-tiny/${VERSION_TAG}/xnnpack/whisper_tiny_xnnpack_fp32.pte`; -const WHISPER_BASE_TOKENIZER = `${URL_PREFIX}-whisper-base/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_BASE_MODEL = `${URL_PREFIX}-whisper-base/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_base_xnnpack.pte`; +const WHISPER_BASE_TOKENIZER = `${URL_PREFIX}-whisper-base/${VERSION_TAG}/tokenizer.json`; +const WHISPER_BASE_MODEL = `${URL_PREFIX}-whisper-base/${VERSION_TAG}/xnnpack/whisper_base_xnnpack_fp32.pte`; -const WHISPER_SMALL_TOKENIZER = `${URL_PREFIX}-whisper-small/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const WHISPER_SMALL_MODEL = `${URL_PREFIX}-whisper-small/${PREVIOUS_VERSION_TAG}/xnnpack/whisper_small_xnnpack.pte`; +const WHISPER_SMALL_TOKENIZER = `${URL_PREFIX}-whisper-small/${VERSION_TAG}/tokenizer.json`; +const WHISPER_SMALL_MODEL = `${URL_PREFIX}-whisper-small/${VERSION_TAG}/xnnpack/whisper_small_xnnpack_fp32.pte`; /** * @category Models - Speech To Text @@ -891,18 +933,18 @@ export const WHISPER_SMALL = { } as const; // Semantic Segmentation -const DEEPLAB_V3_RESNET50_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-resnet50/xnnpack/deeplabv3_resnet50_xnnpack_fp32.pte`; -const DEEPLAB_V3_RESNET101_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-resnet101/xnnpack/deeplabv3_resnet101_xnnpack_fp32.pte`; -const DEEPLAB_V3_MOBILENET_V3_LARGE_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-mobilenet-v3-large/xnnpack/deeplabv3_mobilenet_v3_large_xnnpack_fp32.pte`; -const LRASPP_MOBILENET_V3_LARGE_MODEL = `${URL_PREFIX}-lraspp/${PREVIOUS_VERSION_TAG}/xnnpack/lraspp_mobilenet_v3_large_xnnpack_fp32.pte`; -const FCN_RESNET50_MODEL = `${URL_PREFIX}-fcn/${PREVIOUS_VERSION_TAG}/fcn-resnet50/xnnpack/fcn_resnet50_xnnpack_fp32.pte`; -const FCN_RESNET101_MODEL = `${URL_PREFIX}-fcn/${PREVIOUS_VERSION_TAG}/fcn-resnet101/xnnpack/fcn_resnet101_xnnpack_fp32.pte`; -const DEEPLAB_V3_RESNET50_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-resnet50/xnnpack/deeplabv3_resnet50_xnnpack_int8.pte`; -const DEEPLAB_V3_RESNET101_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-resnet101/xnnpack/deeplabv3_resnet101_xnnpack_int8.pte`; -const DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${PREVIOUS_VERSION_TAG}/deeplab-v3-mobilenet-v3-large/xnnpack/deeplabv3_mobilenet_v3_large_xnnpack_int8.pte`; -const LRASPP_MOBILENET_V3_LARGE_QUANTIZED_MODEL = `${URL_PREFIX}-lraspp/${PREVIOUS_VERSION_TAG}/xnnpack/lraspp_mobilenet_v3_large_xnnpack_int8.pte`; -const FCN_RESNET50_QUANTIZED_MODEL = `${URL_PREFIX}-fcn/${PREVIOUS_VERSION_TAG}/fcn-resnet50/xnnpack/fcn_resnet50_xnnpack_int8.pte`; -const FCN_RESNET101_QUANTIZED_MODEL = `${URL_PREFIX}-fcn/${PREVIOUS_VERSION_TAG}/fcn-resnet101/xnnpack/fcn_resnet101_xnnpack_int8.pte`; +const DEEPLAB_V3_RESNET50_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_resnet50_xnnpack_fp32.pte`; +const DEEPLAB_V3_RESNET101_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_resnet101_xnnpack_fp32.pte`; +const DEEPLAB_V3_MOBILENET_V3_LARGE_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_mobilenet_v3_large_xnnpack_fp32.pte`; +const LRASPP_MOBILENET_V3_LARGE_MODEL = `${URL_PREFIX}-lraspp/${VERSION_TAG}/xnnpack/lraspp_mobilenet_v3_large_xnnpack_fp32.pte`; +const FCN_RESNET50_MODEL = `${URL_PREFIX}-fcn/${VERSION_TAG}/xnnpack/fcn_resnet50_xnnpack_fp32.pte`; +const FCN_RESNET101_MODEL = `${URL_PREFIX}-fcn/${VERSION_TAG}/xnnpack/fcn_resnet101_xnnpack_fp32.pte`; +const DEEPLAB_V3_RESNET50_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_resnet50_xnnpack_int8.pte`; +const DEEPLAB_V3_RESNET101_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_resnet101_xnnpack_int8.pte`; +const DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED_MODEL = `${URL_PREFIX}-deeplab-v3/${VERSION_TAG}/xnnpack/deeplab_v3_mobilenet_v3_large_xnnpack_int8.pte`; +const LRASPP_MOBILENET_V3_LARGE_QUANTIZED_MODEL = `${URL_PREFIX}-lraspp/${VERSION_TAG}/xnnpack/lraspp_mobilenet_v3_large_xnnpack_int8.pte`; +const FCN_RESNET50_QUANTIZED_MODEL = `${URL_PREFIX}-fcn/${VERSION_TAG}/xnnpack/fcn_resnet50_xnnpack_int8.pte`; +const FCN_RESNET101_QUANTIZED_MODEL = `${URL_PREFIX}-fcn/${VERSION_TAG}/xnnpack/fcn_resnet101_xnnpack_int8.pte`; /** * @category Models - Semantic Segmentation @@ -1000,7 +1042,7 @@ export const FCN_RESNET101_QUANTIZED = { modelSource: FCN_RESNET101_QUANTIZED_MODEL, } as const; -const SELFIE_SEGMENTATION_MODEL = `${URL_PREFIX}-selfie-segmentation/${PREVIOUS_VERSION_TAG}/xnnpack/selfie-segmentation.pte`; +const SELFIE_SEGMENTATION_MODEL = `${URL_PREFIX}-selfie-segmentation/${VERSION_TAG}/xnnpack/selfie_segmentation_xnnpack_fp32.pte`; /** * @category Models - Semantic Segmentation @@ -1011,14 +1053,18 @@ export const SELFIE_SEGMENTATION = { } as const; // FastSAM Instance Segmentation +export const FASTSAM_S_XNNPACK_FP32_MODEL = `${URL_PREFIX}-fast-sam/${VERSION_TAG}/s/xnnpack/fast_sam_s_xnnpack_fp32.pte`; +export const FASTSAM_S_COREML_FP16_MODEL = `${URL_PREFIX}-fast-sam/${VERSION_TAG}/s/coreml/fast_sam_s_coreml_fp16.pte`; +export const FASTSAM_X_XNNPACK_FP32_MODEL = `${URL_PREFIX}-fast-sam/${VERSION_TAG}/x/xnnpack/fast_sam_x_xnnpack_fp32.pte`; +export const FASTSAM_X_COREML_FP16_MODEL = `${URL_PREFIX}-fast-sam/${VERSION_TAG}/x/coreml/fast_sam_x_coreml_fp16.pte`; const FASTSAM_S_SEG_MODEL = Platform.OS === 'ios' - ? `${URL_PREFIX}-fast-sam/${VERSION_TAG}/fastsam-s/coreml/fastsam_s_coreml_fp16.pte` - : `${URL_PREFIX}-fast-sam/${VERSION_TAG}/fastsam-s/xnnpack/fastsam_s_xnnpack_fp32.pte`; + ? FASTSAM_S_COREML_FP16_MODEL + : FASTSAM_S_XNNPACK_FP32_MODEL; const FASTSAM_X_SEG_MODEL = Platform.OS === 'ios' - ? `${URL_PREFIX}-fast-sam/${VERSION_TAG}/fastsam-x/coreml/fastsam_x_coreml_fp16.pte` - : `${URL_PREFIX}-fast-sam/${VERSION_TAG}/fastsam-x/xnnpack/fastsam_x_xnnpack_fp32.pte`; + ? FASTSAM_X_COREML_FP16_MODEL + : FASTSAM_X_XNNPACK_FP32_MODEL; /** * @category Models - Instance Segmentation @@ -1039,15 +1085,17 @@ export const FASTSAM_X = { /** * @category Models - Instance Segmentation */ -const YOLO26N_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${PREVIOUS_VERSION_TAG}/yolo26n-seg/xnnpack/yolo26n-seg.pte`; -const YOLO26S_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${PREVIOUS_VERSION_TAG}/yolo26s-seg/xnnpack/yolo26s-seg.pte`; -const YOLO26M_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${PREVIOUS_VERSION_TAG}/yolo26m-seg/xnnpack/yolo26m-seg.pte`; -const YOLO26L_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${PREVIOUS_VERSION_TAG}/yolo26l-seg/xnnpack/yolo26l-seg.pte`; -const YOLO26X_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${PREVIOUS_VERSION_TAG}/yolo26x-seg/xnnpack/yolo26x-seg.pte`; +const YOLO26N_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${VERSION_TAG}/n/xnnpack/yolo26_seg_n_xnnpack_fp32.pte`; +const YOLO26S_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${VERSION_TAG}/s/xnnpack/yolo26_seg_s_xnnpack_fp32.pte`; +const YOLO26M_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${VERSION_TAG}/m/xnnpack/yolo26_seg_m_xnnpack_fp32.pte`; +const YOLO26L_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${VERSION_TAG}/l/xnnpack/yolo26_seg_l_xnnpack_fp32.pte`; +const YOLO26X_SEG_MODEL = `${URL_PREFIX}-yolo26-seg/${VERSION_TAG}/x/xnnpack/yolo26_seg_x_xnnpack_fp32.pte`; +export const RF_DETR_NANO_SEG_XNNPACK_FP32_MODEL = `${URL_PREFIX}-rfdetr-nano-segmentation/${VERSION_TAG}/xnnpack/rfdetr_nano_xnnpack_fp32.pte`; +export const RF_DETR_NANO_SEG_COREML_INT8_MODEL = `${URL_PREFIX}-rfdetr-nano-segmentation/${VERSION_TAG}/coreml/rfdetr_nano_coreml_int8.pte`; const RF_DETR_NANO_SEG_MODEL = Platform.OS === 'ios' - ? `${URL_PREFIX}-rfdetr-nano-segmentation/${PREVIOUS_VERSION_TAG}/coreml/rfdetr_n_seg_coreml_int8.pte` - : `${URL_PREFIX}-rfdetr-nano-segmentation/${PREVIOUS_VERSION_TAG}/rfdetr_segmentation.pte`; + ? RF_DETR_NANO_SEG_COREML_INT8_MODEL + : RF_DETR_NANO_SEG_XNNPACK_FP32_MODEL; /** * @category Models - Instance Segmentation */ @@ -1097,8 +1145,8 @@ export const RF_DETR_NANO_SEG = { } as const; // Image Embeddings -const CLIP_VIT_BASE_PATCH32_IMAGE_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${PREVIOUS_VERSION_TAG}/xnnpack/clip_vit_base_patch32_vision_xnnpack_fp32.pte`; -const CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${PREVIOUS_VERSION_TAG}/xnnpack/clip_vit_base_patch32_vision_xnnpack_int8.pte`; +const CLIP_VIT_BASE_PATCH32_IMAGE_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${VERSION_TAG}/xnnpack/clip_vit_base_patch32_image_xnnpack_fp32.pte`; +const CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${VERSION_TAG}/xnnpack/clip_vit_base_patch32_image_xnnpack_int8.pte`; /** * @category Models - Image Embeddings @@ -1117,21 +1165,21 @@ export const CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED = { } as const; // Text Embeddings -const ALL_MINILM_L6_V2_MODEL = `${URL_PREFIX}-all-MiniLM-L6-v2/${PREVIOUS_VERSION_TAG}/all-MiniLM-L6-v2_xnnpack.pte`; -const ALL_MINILM_L6_V2_TOKENIZER = `${URL_PREFIX}-all-MiniLM-L6-v2/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const ALL_MPNET_BASE_V2_MODEL = `${URL_PREFIX}-all-mpnet-base-v2/${PREVIOUS_VERSION_TAG}/all-mpnet-base-v2_xnnpack.pte`; -const ALL_MPNET_BASE_V2_TOKENIZER = `${URL_PREFIX}-all-mpnet-base-v2/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const MULTI_QA_MINILM_L6_COS_V1_MODEL = `${URL_PREFIX}-multi-qa-MiniLM-L6-cos-v1/${PREVIOUS_VERSION_TAG}/multi-qa-MiniLM-L6-cos-v1_xnnpack.pte`; -const MULTI_QA_MINILM_L6_COS_V1_TOKENIZER = `${URL_PREFIX}-multi-qa-MiniLM-L6-cos-v1/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const MULTI_QA_MPNET_BASE_DOT_V1_MODEL = `${URL_PREFIX}-multi-qa-mpnet-base-dot-v1/${PREVIOUS_VERSION_TAG}/multi-qa-mpnet-base-dot-v1_xnnpack.pte`; -const MULTI_QA_MPNET_BASE_DOT_V1_TOKENIZER = `${URL_PREFIX}-multi-qa-mpnet-base-dot-v1/${PREVIOUS_VERSION_TAG}/tokenizer.json`; -const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W_MODEL = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/xnnpack/distiluse-base-multilingual-cased-v2_xnnpack_8da4w.pte`; -const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML_MODEL = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/coreml/distiluse-base-multilingual-cased-v2_coreml_fp32.pte`; -const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_TOKENIZER = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/tokenizer.json`; -const PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED_MODEL = `${URL_PREFIX}-paraphrase-multilingual-MiniLM-L12-v2/${VERSION_TAG}/xnnpack/paraphrase-multilingual-MiniLM-L12-v2_xnnpack_8da4w.pte`; +const ALL_MINILM_L6_V2_MODEL = `${URL_PREFIX}-all-MiniLM-L6-v2/${VERSION_TAG}/xnnpack/all_minilm_l6_v2_xnnpack_fp32.pte`; +const ALL_MINILM_L6_V2_TOKENIZER = `${URL_PREFIX}-all-MiniLM-L6-v2/${VERSION_TAG}/tokenizer.json`; +const ALL_MPNET_BASE_V2_MODEL = `${URL_PREFIX}-all-mpnet-base-v2/${VERSION_TAG}/xnnpack/all_mpnet_base_v2_xnnpack_fp32.pte`; +const ALL_MPNET_BASE_V2_TOKENIZER = `${URL_PREFIX}-all-mpnet-base-v2/${VERSION_TAG}/tokenizer.json`; +const MULTI_QA_MINILM_L6_COS_V1_MODEL = `${URL_PREFIX}-multi-qa-MiniLM-L6-cos-v1/${VERSION_TAG}/xnnpack/multi_qa_minilm_l6_cos_v1_xnnpack_fp32.pte`; +const MULTI_QA_MINILM_L6_COS_V1_TOKENIZER = `${URL_PREFIX}-multi-qa-MiniLM-L6-cos-v1/${VERSION_TAG}/tokenizer.json`; +const MULTI_QA_MPNET_BASE_DOT_V1_MODEL = `${URL_PREFIX}-multi-qa-mpnet-base-dot-v1/${VERSION_TAG}/xnnpack/multi_qa_mpnet_base_dot_v1_xnnpack_fp32.pte`; +const MULTI_QA_MPNET_BASE_DOT_V1_TOKENIZER = `${URL_PREFIX}-multi-qa-mpnet-base-dot-v1/${VERSION_TAG}/tokenizer.json`; +export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W_MODEL = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/xnnpack/distiluse_base_multilingual_cased_v2_xnnpack_8da4w.pte`; +export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML_MODEL = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/coreml/distiluse_base_multilingual_cased_v2_coreml_fp32.pte`; +export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_TOKENIZER = `${URL_PREFIX}-distiluse-base-multilingual-cased-v2/${VERSION_TAG}/tokenizer.json`; +const PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED_MODEL = `${URL_PREFIX}-paraphrase-multilingual-MiniLM-L12-v2/${VERSION_TAG}/xnnpack/paraphrase_multilingual_minilm_l12_v2_xnnpack_8da4w.pte`; const PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_TOKENIZER = `${URL_PREFIX}-paraphrase-multilingual-MiniLM-L12-v2/${VERSION_TAG}/tokenizer.json`; -const CLIP_VIT_BASE_PATCH32_TEXT_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${PREVIOUS_VERSION_TAG}/xnnpack/clip_vit_base_patch32_text_xnnpack_fp32.pte`; -const CLIP_VIT_BASE_PATCH32_TEXT_TOKENIZER = `${URL_PREFIX}-clip-vit-base-patch32/${PREVIOUS_VERSION_TAG}/tokenizer.json`; +const CLIP_VIT_BASE_PATCH32_TEXT_MODEL = `${URL_PREFIX}-clip-vit-base-patch32/${VERSION_TAG}/xnnpack/clip_vit_base_patch32_text_xnnpack_fp32.pte`; +const CLIP_VIT_BASE_PATCH32_TEXT_TOKENIZER = `${URL_PREFIX}-clip-vit-base-patch32/${VERSION_TAG}/tokenizer.json`; /** * @category Models - Text Embeddings @@ -1171,6 +1219,8 @@ export const MULTI_QA_MPNET_BASE_DOT_V1 = { /** * @category Models - Text Embeddings + * @deprecated Use `MODEL_REGISTRY.TEXT_EMBEDDING.DISTILUSE_BASE_MULTILINGUAL_CASED_V2` + * (defaults to xnnpack on Android) or pass `{ backend: 'xnnpack' }`. */ export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W = { modelName: 'distiluse-base-multilingual-cased-v2-8da4w', @@ -1180,6 +1230,7 @@ export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W = { /** * @category Models - Text Embeddings + * @deprecated Use `MODEL_REGISTRY.TEXT_EMBEDDING.DISTILUSE_BASE_MULTILINGUAL_CASED_V2({ backend: 'coreml' })`. */ export const DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML = { modelName: 'distiluse-base-multilingual-cased-v2-coreml', @@ -1220,7 +1271,7 @@ export const CLIP_VIT_BASE_PATCH32_TEXT = { */ export const PRIVACY_FILTER_OPENAI = { modelName: 'privacy-filter-openai', - modelSource: `${URL_PREFIX}-privacy-filter-openai/${VERSION_TAG}/xnnpack/privacy-filter_xnnpack_8da4w.pte`, + modelSource: `${URL_PREFIX}-privacy-filter-openai/${VERSION_TAG}/xnnpack/privacy_filter_openai_xnnpack_8da4w.pte`, tokenizerSource: `${URL_PREFIX}-privacy-filter-openai/${VERSION_TAG}/tokenizer.json`, labelNames: PRIVACY_FILTER_OPENAI_LABELS, } as const; @@ -1233,7 +1284,7 @@ export const PRIVACY_FILTER_OPENAI = { */ export const PRIVACY_FILTER_NEMOTRON = { modelName: 'privacy-filter-nemotron', - modelSource: `${URL_PREFIX}-privacy-filter-nemotron/${VERSION_TAG}/xnnpack/privacy-filter-nemotron_xnnpack_8da4w.pte`, + modelSource: `${URL_PREFIX}-privacy-filter-nemotron/${VERSION_TAG}/xnnpack/privacy_filter_nemotron_xnnpack_8da4w.pte`, tokenizerSource: `${URL_PREFIX}-privacy-filter-nemotron/${VERSION_TAG}/tokenizer.json`, labelNames: PRIVACY_FILTER_NEMOTRON_LABELS, } as const; @@ -1245,11 +1296,11 @@ export const PRIVACY_FILTER_NEMOTRON = { */ export const BK_SDM_TINY_VPRED_512 = { modelName: 'bk-sdm-tiny-vpred-512', - schedulerSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/scheduler/scheduler_config.json`, - tokenizerSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/tokenizer/tokenizer.json`, - encoderSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/text_encoder/model.pte`, - unetSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/unet/model.pte`, - decoderSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/vae/model.pte`, + schedulerSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/scheduler/scheduler_config.json`, + tokenizerSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/tokenizer/tokenizer.json`, + encoderSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_text_encoder_xnnpack_fp32.pte`, + unetSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_unet_xnnpack_fp32.pte`, + decoderSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_vae_xnnpack_fp32.pte`, } as const; /** @@ -1257,15 +1308,15 @@ export const BK_SDM_TINY_VPRED_512 = { */ export const BK_SDM_TINY_VPRED_256 = { modelName: 'bk-sdm-tiny-vpred-256', - schedulerSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/scheduler/scheduler_config.json`, - tokenizerSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/tokenizer/tokenizer.json`, - encoderSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/text_encoder/model.pte`, - unetSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/unet/model.256.pte`, - decoderSource: `${URL_PREFIX}-bk-sdm-tiny/${PREVIOUS_VERSION_TAG}/vae/model.256.pte`, + schedulerSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/scheduler/scheduler_config.json`, + tokenizerSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/tokenizer/tokenizer.json`, + encoderSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_text_encoder_xnnpack_fp32.pte`, + unetSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_unet_256_xnnpack_fp32.pte`, + decoderSource: `${URL_PREFIX}-bk-sdm-tiny/${VERSION_TAG}/xnnpack/bk_sdm_tiny_vae_256_xnnpack_fp32.pte`, } as const; // Voice Activity Detection -const FSMN_VAD_MODEL = `${URL_PREFIX}-fsmn-vad/${PREVIOUS_VERSION_TAG}/xnnpack/fsmn-vad_xnnpack.pte`; +const FSMN_VAD_MODEL = `${URL_PREFIX}-fsmn-vad/${VERSION_TAG}/xnnpack/fsmn_vad_xnnpack_fp32.pte`; /** * @category Models - Voice Activity Detection @@ -1275,131 +1326,112 @@ export const FSMN_VAD = { modelSource: FSMN_VAD_MODEL, } as const; -/** - * Registry of all available model configurations. - * - * Use this to discover and enumerate all models shipped with the library. - * @example - * ```ts - * import { MODEL_REGISTRY } from 'react-native-executorch'; - * - * // List all model names - * const names = Object.values(MODEL_REGISTRY).map(m => m.modelName); - * - * // Find models by name substring - * const whisperModels = Object.values(MODEL_REGISTRY) - * .filter(m => m.modelName.includes('whisper')); - * ``` - * @category Utils - */ -export const MODEL_REGISTRY = { - ALL_MODELS: { - LLAMA3_2_3B, - LLAMA3_2_3B_QLORA, - LLAMA3_2_3B_SPINQUANT, - LLAMA3_2_1B, - LLAMA3_2_1B_QLORA, - LLAMA3_2_1B_SPINQUANT, - QWEN3_0_6B, - QWEN3_0_6B_QUANTIZED, - QWEN3_1_7B, - QWEN3_1_7B_QUANTIZED, - QWEN3_4B, - QWEN3_4B_QUANTIZED, - QWEN3_5_0_8B_QUANTIZED, - QWEN3_5_2B_QUANTIZED, - HAMMER2_1_0_5B, - HAMMER2_1_0_5B_QUANTIZED, - HAMMER2_1_1_5B, - HAMMER2_1_1_5B_QUANTIZED, - HAMMER2_1_3B, - HAMMER2_1_3B_QUANTIZED, - SMOLLM2_1_135M, - SMOLLM2_1_135M_QUANTIZED, - SMOLLM2_1_360M, - SMOLLM2_1_360M_QUANTIZED, - SMOLLM2_1_1_7B, - SMOLLM2_1_1_7B_QUANTIZED, - QWEN2_5_0_5B, - QWEN2_5_0_5B_QUANTIZED, - QWEN2_5_1_5B, - QWEN2_5_1_5B_QUANTIZED, - QWEN2_5_3B, - QWEN2_5_3B_QUANTIZED, - PHI_4_MINI_4B, - PHI_4_MINI_4B_QUANTIZED, - LFM2_5_350M, - LFM2_5_350M_QUANTIZED, - LFM2_5_1_2B_INSTRUCT, - LFM2_5_1_2B_INSTRUCT_QUANTIZED, - LFM2_5_VL_1_6B_QUANTIZED, - LFM2_5_VL_450M_QUANTIZED, - LFM2_VL_1_6B_QUANTIZED, - LFM2_VL_450M_QUANTIZED, - BIELIK_V3_0_1_5B, - BIELIK_V3_0_1_5B_QUANTIZED, - EFFICIENTNET_V2_S, - EFFICIENTNET_V2_S_QUANTIZED, - SSDLITE_320_MOBILENET_V3_LARGE, - RF_DETR_NANO, - STYLE_TRANSFER_CANDY, - STYLE_TRANSFER_CANDY_QUANTIZED, - STYLE_TRANSFER_MOSAIC, - STYLE_TRANSFER_MOSAIC_QUANTIZED, - STYLE_TRANSFER_RAIN_PRINCESS, - STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED, - STYLE_TRANSFER_UDNIE, - STYLE_TRANSFER_UDNIE_QUANTIZED, - WHISPER_TINY_EN, - WHISPER_TINY_EN_QUANTIZED, - WHISPER_BASE_EN, - WHISPER_BASE_EN_QUANTIZED, - WHISPER_SMALL_EN, - WHISPER_SMALL_EN_QUANTIZED, - WHISPER_TINY, - WHISPER_BASE, - WHISPER_SMALL, - DEEPLAB_V3_RESNET50, - DEEPLAB_V3_RESNET101, - DEEPLAB_V3_MOBILENET_V3_LARGE, - LRASPP_MOBILENET_V3_LARGE, - FCN_RESNET50, - FCN_RESNET101, - DEEPLAB_V3_RESNET50_QUANTIZED, - DEEPLAB_V3_RESNET101_QUANTIZED, - DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, - LRASPP_MOBILENET_V3_LARGE_QUANTIZED, - FCN_RESNET50_QUANTIZED, - FCN_RESNET101_QUANTIZED, - SELFIE_SEGMENTATION, - YOLO26N_SEG, - YOLO26S_SEG, - YOLO26M_SEG, - YOLO26L_SEG, - YOLO26X_SEG, - RF_DETR_NANO_SEG, - FASTSAM_S, - FASTSAM_X, - CLIP_VIT_BASE_PATCH32_IMAGE, - CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED, - ALL_MINILM_L6_V2, - ALL_MPNET_BASE_V2, - MULTI_QA_MINILM_L6_COS_V1, - MULTI_QA_MPNET_BASE_DOT_V1, - DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W, - DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML, - PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED, - CLIP_VIT_BASE_PATCH32_TEXT, - BK_SDM_TINY_VPRED_512, - BK_SDM_TINY_VPRED_256, - FSMN_VAD, - PRIVACY_FILTER_OPENAI, - PRIVACY_FILTER_NEMOTRON, - }, -} as const; +// Internal — populates the urlToModelName lookup below. Not exported: the +// typed grouping lives in `./modelRegistry` as MODEL_REGISTRY. +const _ALL_MODELS = [ + LLAMA3_2_3B, + LLAMA3_2_3B_QLORA, + LLAMA3_2_3B_SPINQUANT, + LLAMA3_2_1B, + LLAMA3_2_1B_QLORA, + LLAMA3_2_1B_SPINQUANT, + QWEN3_0_6B, + QWEN3_0_6B_QUANTIZED, + QWEN3_1_7B, + QWEN3_1_7B_QUANTIZED, + QWEN3_4B, + QWEN3_4B_QUANTIZED, + QWEN3_5_0_8B_QUANTIZED, + QWEN3_5_2B_QUANTIZED, + HAMMER2_1_0_5B, + HAMMER2_1_0_5B_QUANTIZED, + HAMMER2_1_1_5B, + HAMMER2_1_1_5B_QUANTIZED, + HAMMER2_1_3B, + HAMMER2_1_3B_QUANTIZED, + SMOLLM2_1_135M, + SMOLLM2_1_135M_QUANTIZED, + SMOLLM2_1_360M, + SMOLLM2_1_360M_QUANTIZED, + SMOLLM2_1_1_7B, + SMOLLM2_1_1_7B_QUANTIZED, + QWEN2_5_0_5B, + QWEN2_5_0_5B_QUANTIZED, + QWEN2_5_1_5B, + QWEN2_5_1_5B_QUANTIZED, + QWEN2_5_3B, + QWEN2_5_3B_QUANTIZED, + PHI_4_MINI_4B, + PHI_4_MINI_4B_QUANTIZED, + LFM2_5_350M, + LFM2_5_350M_QUANTIZED, + LFM2_5_1_2B_INSTRUCT, + LFM2_5_1_2B_INSTRUCT_QUANTIZED, + LFM2_5_VL_1_6B_QUANTIZED, + LFM2_5_VL_450M_QUANTIZED, + BIELIK_V3_0_1_5B, + BIELIK_V3_0_1_5B_QUANTIZED, + EFFICIENTNET_V2_S, + EFFICIENTNET_V2_S_QUANTIZED, + SSDLITE_320_MOBILENET_V3_LARGE, + RF_DETR_NANO, + STYLE_TRANSFER_CANDY, + STYLE_TRANSFER_CANDY_QUANTIZED, + STYLE_TRANSFER_MOSAIC, + STYLE_TRANSFER_MOSAIC_QUANTIZED, + STYLE_TRANSFER_RAIN_PRINCESS, + STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED, + STYLE_TRANSFER_UDNIE, + STYLE_TRANSFER_UDNIE_QUANTIZED, + WHISPER_TINY_EN, + WHISPER_TINY_EN_QUANTIZED, + WHISPER_BASE_EN, + WHISPER_BASE_EN_QUANTIZED, + WHISPER_SMALL_EN, + WHISPER_SMALL_EN_QUANTIZED, + WHISPER_TINY, + WHISPER_BASE, + WHISPER_SMALL, + DEEPLAB_V3_RESNET50, + DEEPLAB_V3_RESNET101, + DEEPLAB_V3_MOBILENET_V3_LARGE, + LRASPP_MOBILENET_V3_LARGE, + FCN_RESNET50, + FCN_RESNET101, + DEEPLAB_V3_RESNET50_QUANTIZED, + DEEPLAB_V3_RESNET101_QUANTIZED, + DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED, + LRASPP_MOBILENET_V3_LARGE_QUANTIZED, + FCN_RESNET50_QUANTIZED, + FCN_RESNET101_QUANTIZED, + SELFIE_SEGMENTATION, + YOLO26N_SEG, + YOLO26S_SEG, + YOLO26M_SEG, + YOLO26L_SEG, + YOLO26X_SEG, + RF_DETR_NANO_SEG, + FASTSAM_S, + FASTSAM_X, + CLIP_VIT_BASE_PATCH32_IMAGE, + CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED, + ALL_MINILM_L6_V2, + ALL_MPNET_BASE_V2, + MULTI_QA_MINILM_L6_COS_V1, + MULTI_QA_MPNET_BASE_DOT_V1, + DISTILUSE_BASE_MULTILINGUAL_CASED_V2_8DA4W, + DISTILUSE_BASE_MULTILINGUAL_CASED_V2_COREML, + PARAPHRASE_MULTILINGUAL_MINILM_L12_V2_QUANTIZED, + CLIP_VIT_BASE_PATCH32_TEXT, + BK_SDM_TINY_VPRED_512, + BK_SDM_TINY_VPRED_256, + FSMN_VAD, + PRIVACY_FILTER_OPENAI, + PRIVACY_FILTER_NEMOTRON, +]; const urlToModelName = new Map(); -for (const config of Object.values(MODEL_REGISTRY.ALL_MODELS)) { +for (const config of _ALL_MODELS) { const modelName = config.modelName; for (const [key, value] of Object.entries(config)) { if (key !== 'modelName' && typeof value === 'string') { diff --git a/packages/react-native-executorch/src/constants/ocr/models.ts b/packages/react-native-executorch/src/constants/ocr/models.ts index 990156a8bd..b906f6f12b 100644 --- a/packages/react-native-executorch/src/constants/ocr/models.ts +++ b/packages/react-native-executorch/src/constants/ocr/models.ts @@ -1,11 +1,11 @@ import { alphabets, symbols } from './symbols'; -import { URL_PREFIX, PREVIOUS_VERSION_TAG } from '../versions'; +import { URL_PREFIX, VERSION_TAG } from '../versions'; -const DETECTOR_CRAFT_MODEL = `${URL_PREFIX}-detector-craft/${PREVIOUS_VERSION_TAG}/xnnpack_quantized/xnnpack_craft_quantized.pte`; +const DETECTOR_CRAFT_MODEL = `${URL_PREFIX}-detector-craft/${VERSION_TAG}/xnnpack/craft_xnnpack_int8.pte`; const createHFRecognizerDownloadUrl = (alphabet: keyof typeof alphabets) => - `${URL_PREFIX}-recognizer-crnn.en/${PREVIOUS_VERSION_TAG}/xnnpack/${alphabet}/xnnpack_crnn_${alphabet}.pte`; + `${URL_PREFIX}-recognizer-crnn.en/${VERSION_TAG}/${alphabet}/xnnpack/crnn_${alphabet}_xnnpack_fp32.pte`; const RECOGNIZER_ENGLISH_CRNN = createHFRecognizerDownloadUrl('english'); const RECOGNIZER_LATIN_CRNN = createHFRecognizerDownloadUrl('latin'); diff --git a/packages/react-native-executorch/src/constants/tts/models.ts b/packages/react-native-executorch/src/constants/tts/models.ts index e1afd989fc..ca3089c517 100644 --- a/packages/react-native-executorch/src/constants/tts/models.ts +++ b/packages/react-native-executorch/src/constants/tts/models.ts @@ -1,9 +1,9 @@ -import { URL_PREFIX, PREVIOUS_VERSION_TAG } from '../versions'; +import { URL_PREFIX, VERSION_TAG } from '../versions'; // Text to speech (tts) - Kokoro model(s) -const KOKORO_EN_MODELS_ROOT = `${URL_PREFIX}-kokoro/${PREVIOUS_VERSION_TAG}/xnnpack`; -const KOKORO_EN_SMALL_MODELS_ROOT = `${KOKORO_EN_MODELS_ROOT}/small`; -const KOKORO_EN_MEDIUM_MODELS_ROOT = `${KOKORO_EN_MODELS_ROOT}/medium`; +const KOKORO_ROOT = `${URL_PREFIX}-kokoro/${VERSION_TAG}`; +const KOKORO_SMALL_BACKEND_ROOT = `${KOKORO_ROOT}/small/xnnpack`; +const KOKORO_MEDIUM_BACKEND_ROOT = `${KOKORO_ROOT}/medium/xnnpack`; /** * A Kokoro model instance which processes the text in batches of maximum 64 tokens. @@ -13,8 +13,8 @@ const KOKORO_EN_MEDIUM_MODELS_ROOT = `${KOKORO_EN_MODELS_ROOT}/medium`; */ export const KOKORO_SMALL = { modelName: 'kokoro-small' as const, - durationPredictorSource: `${KOKORO_EN_SMALL_MODELS_ROOT}/duration_predictor.pte`, - synthesizerSource: `${KOKORO_EN_SMALL_MODELS_ROOT}/synthesizer.pte`, + durationPredictorSource: `${KOKORO_SMALL_BACKEND_ROOT}/kokoro_small_duration_predictor_xnnpack_fp32.pte`, + synthesizerSource: `${KOKORO_SMALL_BACKEND_ROOT}/kokoro_small_synthesizer_xnnpack_fp32.pte`, }; /** @@ -23,6 +23,6 @@ export const KOKORO_SMALL = { */ export const KOKORO_MEDIUM = { modelName: 'kokoro-medium' as const, - durationPredictorSource: `${KOKORO_EN_MEDIUM_MODELS_ROOT}/duration_predictor.pte`, - synthesizerSource: `${KOKORO_EN_MEDIUM_MODELS_ROOT}/synthesizer.pte`, + durationPredictorSource: `${KOKORO_MEDIUM_BACKEND_ROOT}/kokoro_medium_duration_predictor_xnnpack_fp32.pte`, + synthesizerSource: `${KOKORO_MEDIUM_BACKEND_ROOT}/kokoro_medium_synthesizer_xnnpack_fp32.pte`, }; diff --git a/packages/react-native-executorch/src/constants/versions.ts b/packages/react-native-executorch/src/constants/versions.ts index 9ce8a726d8..c272d992fe 100644 --- a/packages/react-native-executorch/src/constants/versions.ts +++ b/packages/react-native-executorch/src/constants/versions.ts @@ -2,5 +2,7 @@ export const LIB_VERSION = '0.9.0'; export const URL_PREFIX = 'https://huggingface.co/software-mansion/react-native-executorch'; +// Used by @deprecated constants that still resolve v0.8.0 files (e.g. the +// Llama QLoRA aliases superseded by SpinQuant). export const PREVIOUS_VERSION_TAG = 'resolve/v0.8.0'; export const VERSION_TAG = `resolve/v${LIB_VERSION}`; diff --git a/packages/react-native-executorch/src/index.ts b/packages/react-native-executorch/src/index.ts index 84d6da5150..6f54dbc02d 100644 --- a/packages/react-native-executorch/src/index.ts +++ b/packages/react-native-executorch/src/index.ts @@ -238,6 +238,7 @@ export * from './types/poseEstimation'; export * from './constants/commonVision'; export * from './constants/classification'; export * from './constants/modelUrls'; +export * from './constants/modelRegistry'; export * from './constants/ocr/models'; export * from './constants/tts/models'; export * from './constants/tts/voices';