nexaai 1.0.4rc10__py3-none-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nexaai might be problematic. Click here for more details.
- nexaai/__init__.py +71 -0
- nexaai/_version.py +4 -0
- nexaai/asr.py +60 -0
- nexaai/asr_impl/__init__.py +0 -0
- nexaai/asr_impl/mlx_asr_impl.py +91 -0
- nexaai/asr_impl/pybind_asr_impl.py +43 -0
- nexaai/base.py +39 -0
- nexaai/binds/__init__.py +3 -0
- nexaai/binds/common_bind.cpython-310-darwin.so +0 -0
- nexaai/binds/embedder_bind.cpython-310-darwin.so +0 -0
- nexaai/binds/libnexa_bridge.dylib +0 -0
- nexaai/binds/llm_bind.cpython-310-darwin.so +0 -0
- nexaai/binds/nexa_llama_cpp/libggml-base.dylib +0 -0
- nexaai/binds/nexa_llama_cpp/libggml-cpu.so +0 -0
- nexaai/binds/nexa_llama_cpp/libggml-metal.so +0 -0
- nexaai/binds/nexa_llama_cpp/libggml.dylib +0 -0
- nexaai/binds/nexa_llama_cpp/libllama.dylib +0 -0
- nexaai/binds/nexa_llama_cpp/libmtmd.dylib +0 -0
- nexaai/binds/nexa_llama_cpp/libnexa_plugin.dylib +0 -0
- nexaai/binds/nexa_mlx/libnexa_plugin.dylib +0 -0
- nexaai/binds/nexa_mlx/py-lib/ml.py +842 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/__init__.py +5 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/activation.py +51 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/amp.py +96 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/bigvgan.py +149 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/conv.py +114 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/bigvgan/resample.py +177 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/base.py +228 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/dac.py +285 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/nn/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/nn/layers.py +129 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/descript/nn/quantize.py +149 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/encodec/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/encodec/encodec.py +777 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/mimi.py +286 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/__init__.py +20 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/conv.py +398 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/kv_cache.py +199 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/quantization.py +179 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/seanet.py +314 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/mimi/modules/transformer.py +256 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/s3/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/s3/model.py +260 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/s3/model_v2.py +383 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/s3/utils.py +122 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/snac/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/snac/attention.py +97 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/snac/layers.py +306 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/snac/snac.py +154 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/snac/vq.py +135 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/vocos/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/vocos/mel.py +33 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/models/vocos/vocos.py +359 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_bigvgan.py +54 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_descript.py +109 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_encodec.py +58 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_mimi.py +22 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_s3.py +25 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_snac.py +40 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/codec/tests/test_vocos.py +93 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/server.py +525 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/sts/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/sts/tests/test_voice_pipeline.py +156 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/sts/voice_pipeline.py +327 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/generate.py +174 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/alignment.py +248 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/attention.py +187 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/audio.py +76 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/conformer.py +331 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/ctc.py +34 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/parakeet.py +604 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/rnnt.py +157 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/parakeet/tokenizer.py +2 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/wav2vec/feature_extractor.py +757 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/wav2vec/wav2vec.py +738 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/audio.py +82 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/decoding.py +742 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/timing.py +329 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/tokenizer.py +398 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/whisper.py +862 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/models/whisper/writers.py +268 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/tests/test_models.py +381 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/stt/utils.py +195 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/audio_player.py +120 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/convert.py +71 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/generate.py +449 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/bark/__init__.py +4 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/bark/bark.py +528 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/bark/isftnet.py +12 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/bark/pipeline.py +442 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/base.py +84 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/dia/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/dia/audio.py +287 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/dia/config.py +256 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/dia/dia.py +592 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/dia/layers.py +870 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/__init__.py +3 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/attention.py +180 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/bigvgan.py +124 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/conformer.py +247 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/ecapa_tdnn/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/ecapa_tdnn/asp.py +59 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/ecapa_tdnn/ecapa_tdnn.py +91 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/ecapa_tdnn/se_res2net.py +132 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/ecapa_tdnn/tdnn.py +42 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/gpt2.py +38 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/indextts.py +412 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/mel.py +37 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/normalize.py +294 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/indextts/perceiver.py +62 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/interpolate.py +108 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/__init__.py +4 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/istftnet.py +979 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/kokoro.py +331 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/modules.py +659 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/pipeline.py +453 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/kokoro/voice.py +113 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/llama/__init__.py +3 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/llama/llama.py +324 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/audio_processor.py +351 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/dac_interface.py +162 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/outetts.py +255 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/prompt_processor.py +181 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/outetts/tokens.py +36 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/sesame/__init__.py +3 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/sesame/attention.py +195 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/sesame/sesame.py +633 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/sesame/watermarking.py +105 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/audio_tokenizer.py +138 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/bicodec.py +269 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/blocks/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/blocks/sampler.py +111 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/encoder_decoder/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/encoder_decoder/feat_decoder.py +120 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/encoder_decoder/feat_encoder.py +136 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/encoder_decoder/wave_generator.py +113 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/finite_scalar_quantization.py +238 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/residual.py +209 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/residual_fsq.py +309 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/speaker/__init__.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/speaker/ecapa_tdnn.py +283 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/speaker/perceiver_encoder.py +326 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/speaker/pooling_layers.py +297 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/modules/speaker/speaker_encoder.py +155 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/spark.py +382 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/utils/audio.py +220 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/utils/file.py +221 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/models/spark/utils/token_parser.py +181 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/tests/__init__.py +0 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/tests/test_base.py +66 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/tests/test_convert.py +173 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/tests/test_interpolate.py +88 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/tests/test_models.py +974 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/tts/utils.py +337 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/utils.py +237 -0
- nexaai/binds/nexa_mlx/py-lib/mlx_audio/version.py +1 -0
- nexaai/binds/nexa_mlx/py-lib/profiling.py +239 -0
- nexaai/common.py +61 -0
- nexaai/cv.py +87 -0
- nexaai/cv_impl/__init__.py +0 -0
- nexaai/cv_impl/mlx_cv_impl.py +88 -0
- nexaai/cv_impl/pybind_cv_impl.py +31 -0
- nexaai/embedder.py +68 -0
- nexaai/embedder_impl/__init__.py +0 -0
- nexaai/embedder_impl/mlx_embedder_impl.py +114 -0
- nexaai/embedder_impl/pybind_embedder_impl.py +91 -0
- nexaai/image_gen.py +136 -0
- nexaai/image_gen_impl/__init__.py +0 -0
- nexaai/image_gen_impl/mlx_image_gen_impl.py +291 -0
- nexaai/image_gen_impl/pybind_image_gen_impl.py +84 -0
- nexaai/llm.py +89 -0
- nexaai/llm_impl/__init__.py +0 -0
- nexaai/llm_impl/mlx_llm_impl.py +249 -0
- nexaai/llm_impl/pybind_llm_impl.py +207 -0
- nexaai/mlx_backend/asr/__init__.py +12 -0
- nexaai/mlx_backend/asr/interface.py +122 -0
- nexaai/mlx_backend/common/__init__.py +0 -0
- nexaai/mlx_backend/common/utils.py +25 -0
- nexaai/mlx_backend/cv/__init__.py +0 -0
- nexaai/mlx_backend/cv/generate.py +195 -0
- nexaai/mlx_backend/cv/interface.py +151 -0
- nexaai/mlx_backend/cv/main.py +81 -0
- nexaai/mlx_backend/cv/modeling/pp_ocr_v4.py +1736 -0
- nexaai/mlx_backend/embedding/__init__.py +0 -0
- nexaai/mlx_backend/embedding/generate.py +130 -0
- nexaai/mlx_backend/embedding/interface.py +312 -0
- nexaai/mlx_backend/embedding/main.py +82 -0
- nexaai/mlx_backend/embedding/modeling/__init__.py +0 -0
- nexaai/mlx_backend/embedding/modeling/nexa_jina_v2.py +399 -0
- nexaai/mlx_backend/llm/__init__.py +0 -0
- nexaai/mlx_backend/llm/generate.py +149 -0
- nexaai/mlx_backend/llm/interface.py +764 -0
- nexaai/mlx_backend/llm/main.py +68 -0
- nexaai/mlx_backend/ml.py +842 -0
- nexaai/mlx_backend/mlx_audio/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/codec/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/__init__.py +5 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/activation.py +51 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/amp.py +96 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/bigvgan.py +149 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/conv.py +114 -0
- nexaai/mlx_backend/mlx_audio/codec/models/bigvgan/resample.py +177 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/base.py +228 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/dac.py +285 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/nn/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/nn/layers.py +129 -0
- nexaai/mlx_backend/mlx_audio/codec/models/descript/nn/quantize.py +149 -0
- nexaai/mlx_backend/mlx_audio/codec/models/encodec/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/encodec/encodec.py +777 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/mimi.py +286 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/__init__.py +20 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/conv.py +398 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/kv_cache.py +199 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/quantization.py +179 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/seanet.py +314 -0
- nexaai/mlx_backend/mlx_audio/codec/models/mimi/modules/transformer.py +256 -0
- nexaai/mlx_backend/mlx_audio/codec/models/s3/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/s3/model.py +260 -0
- nexaai/mlx_backend/mlx_audio/codec/models/s3/model_v2.py +383 -0
- nexaai/mlx_backend/mlx_audio/codec/models/s3/utils.py +122 -0
- nexaai/mlx_backend/mlx_audio/codec/models/snac/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/snac/attention.py +97 -0
- nexaai/mlx_backend/mlx_audio/codec/models/snac/layers.py +306 -0
- nexaai/mlx_backend/mlx_audio/codec/models/snac/snac.py +154 -0
- nexaai/mlx_backend/mlx_audio/codec/models/snac/vq.py +135 -0
- nexaai/mlx_backend/mlx_audio/codec/models/vocos/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/codec/models/vocos/mel.py +33 -0
- nexaai/mlx_backend/mlx_audio/codec/models/vocos/vocos.py +359 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_bigvgan.py +54 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_descript.py +109 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_encodec.py +58 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_mimi.py +22 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_s3.py +25 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_snac.py +40 -0
- nexaai/mlx_backend/mlx_audio/codec/tests/test_vocos.py +93 -0
- nexaai/mlx_backend/mlx_audio/server.py +525 -0
- nexaai/mlx_backend/mlx_audio/sts/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/sts/tests/test_voice_pipeline.py +156 -0
- nexaai/mlx_backend/mlx_audio/sts/voice_pipeline.py +327 -0
- nexaai/mlx_backend/mlx_audio/stt/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/stt/generate.py +174 -0
- nexaai/mlx_backend/mlx_audio/stt/models/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/alignment.py +248 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/attention.py +187 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/audio.py +76 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/conformer.py +331 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/ctc.py +34 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/parakeet.py +604 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/rnnt.py +157 -0
- nexaai/mlx_backend/mlx_audio/stt/models/parakeet/tokenizer.py +2 -0
- nexaai/mlx_backend/mlx_audio/stt/models/wav2vec/feature_extractor.py +757 -0
- nexaai/mlx_backend/mlx_audio/stt/models/wav2vec/wav2vec.py +738 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/audio.py +82 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/decoding.py +742 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/timing.py +329 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/tokenizer.py +398 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/whisper.py +862 -0
- nexaai/mlx_backend/mlx_audio/stt/models/whisper/writers.py +268 -0
- nexaai/mlx_backend/mlx_audio/stt/tests/test_models.py +381 -0
- nexaai/mlx_backend/mlx_audio/stt/utils.py +195 -0
- nexaai/mlx_backend/mlx_audio/tts/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/tts/audio_player.py +120 -0
- nexaai/mlx_backend/mlx_audio/tts/convert.py +71 -0
- nexaai/mlx_backend/mlx_audio/tts/generate.py +449 -0
- nexaai/mlx_backend/mlx_audio/tts/models/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/models/bark/__init__.py +4 -0
- nexaai/mlx_backend/mlx_audio/tts/models/bark/bark.py +528 -0
- nexaai/mlx_backend/mlx_audio/tts/models/bark/isftnet.py +12 -0
- nexaai/mlx_backend/mlx_audio/tts/models/bark/pipeline.py +442 -0
- nexaai/mlx_backend/mlx_audio/tts/models/base.py +84 -0
- nexaai/mlx_backend/mlx_audio/tts/models/dia/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/tts/models/dia/audio.py +287 -0
- nexaai/mlx_backend/mlx_audio/tts/models/dia/config.py +256 -0
- nexaai/mlx_backend/mlx_audio/tts/models/dia/dia.py +592 -0
- nexaai/mlx_backend/mlx_audio/tts/models/dia/layers.py +870 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/__init__.py +3 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/attention.py +180 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/bigvgan.py +124 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/conformer.py +247 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/ecapa_tdnn/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/ecapa_tdnn/asp.py +59 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/ecapa_tdnn/ecapa_tdnn.py +91 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/ecapa_tdnn/se_res2net.py +132 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/ecapa_tdnn/tdnn.py +42 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/gpt2.py +38 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/indextts.py +412 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/mel.py +37 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/normalize.py +294 -0
- nexaai/mlx_backend/mlx_audio/tts/models/indextts/perceiver.py +62 -0
- nexaai/mlx_backend/mlx_audio/tts/models/interpolate.py +108 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/__init__.py +4 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/istftnet.py +979 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/kokoro.py +331 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/modules.py +659 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/pipeline.py +453 -0
- nexaai/mlx_backend/mlx_audio/tts/models/kokoro/voice.py +113 -0
- nexaai/mlx_backend/mlx_audio/tts/models/llama/__init__.py +3 -0
- nexaai/mlx_backend/mlx_audio/tts/models/llama/llama.py +324 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/audio_processor.py +351 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/dac_interface.py +162 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/default_speaker.json +461 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/outetts.py +255 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/prompt_processor.py +181 -0
- nexaai/mlx_backend/mlx_audio/tts/models/outetts/tokens.py +36 -0
- nexaai/mlx_backend/mlx_audio/tts/models/sesame/__init__.py +3 -0
- nexaai/mlx_backend/mlx_audio/tts/models/sesame/attention.py +195 -0
- nexaai/mlx_backend/mlx_audio/tts/models/sesame/sesame.py +633 -0
- nexaai/mlx_backend/mlx_audio/tts/models/sesame/watermarking.py +105 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/audio_tokenizer.py +138 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/bicodec.py +269 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/blocks/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/blocks/sampler.py +111 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/encoder_decoder/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/encoder_decoder/feat_decoder.py +120 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/encoder_decoder/feat_encoder.py +136 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/encoder_decoder/wave_generator.py +113 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/finite_scalar_quantization.py +238 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/residual.py +209 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/residual_fsq.py +309 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/speaker/__init__.py +1 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/speaker/ecapa_tdnn.py +283 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/speaker/perceiver_encoder.py +326 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/speaker/pooling_layers.py +297 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/modules/speaker/speaker_encoder.py +155 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/spark.py +382 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/utils/audio.py +220 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/utils/file.py +221 -0
- nexaai/mlx_backend/mlx_audio/tts/models/spark/utils/token_parser.py +181 -0
- nexaai/mlx_backend/mlx_audio/tts/tests/__init__.py +0 -0
- nexaai/mlx_backend/mlx_audio/tts/tests/test_base.py +66 -0
- nexaai/mlx_backend/mlx_audio/tts/tests/test_convert.py +173 -0
- nexaai/mlx_backend/mlx_audio/tts/tests/test_interpolate.py +88 -0
- nexaai/mlx_backend/mlx_audio/tts/tests/test_models.py +974 -0
- nexaai/mlx_backend/mlx_audio/tts/utils.py +337 -0
- nexaai/mlx_backend/mlx_audio/utils.py +237 -0
- nexaai/mlx_backend/mlx_audio/version.py +1 -0
- nexaai/mlx_backend/profiling.py +239 -0
- nexaai/mlx_backend/rerank/__init__.py +0 -0
- nexaai/mlx_backend/rerank/generate.py +174 -0
- nexaai/mlx_backend/rerank/interface.py +287 -0
- nexaai/mlx_backend/rerank/main.py +127 -0
- nexaai/mlx_backend/rerank/modeling/__init__.py +0 -0
- nexaai/mlx_backend/rerank/modeling/nexa_jina_rerank.py +330 -0
- nexaai/mlx_backend/sd/__init__.py +1 -0
- nexaai/mlx_backend/sd/interface.py +362 -0
- nexaai/mlx_backend/sd/main.py +286 -0
- nexaai/mlx_backend/sd/modeling/__init__.py +306 -0
- nexaai/mlx_backend/sd/modeling/clip.py +116 -0
- nexaai/mlx_backend/sd/modeling/config.py +65 -0
- nexaai/mlx_backend/sd/modeling/model_io.py +330 -0
- nexaai/mlx_backend/sd/modeling/sampler.py +105 -0
- nexaai/mlx_backend/sd/modeling/tokenizer.py +100 -0
- nexaai/mlx_backend/sd/modeling/unet.py +460 -0
- nexaai/mlx_backend/sd/modeling/vae.py +274 -0
- nexaai/mlx_backend/tts/__init__.py +12 -0
- nexaai/mlx_backend/tts/interface.py +276 -0
- nexaai/mlx_backend/vlm/__init__.py +3 -0
- nexaai/mlx_backend/vlm/generate.py +572 -0
- nexaai/mlx_backend/vlm/interface.py +406 -0
- nexaai/mlx_backend/vlm/main.py +157 -0
- nexaai/mlx_backend/vlm/modeling/__init__.py +0 -0
- nexaai/mlx_backend/vlm/modeling/convert.py +68 -0
- nexaai/mlx_backend/vlm/modeling/models/__init__.py +0 -0
- nexaai/mlx_backend/vlm/modeling/models/aya_vision/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/aya_vision/aya_vision.py +193 -0
- nexaai/mlx_backend/vlm/modeling/models/aya_vision/interpolate.py +186 -0
- nexaai/mlx_backend/vlm/modeling/models/aya_vision/language.py +233 -0
- nexaai/mlx_backend/vlm/modeling/models/aya_vision/vision.py +503 -0
- nexaai/mlx_backend/vlm/modeling/models/base.py +202 -0
- nexaai/mlx_backend/vlm/modeling/models/cache.py +230 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/__init__.py +10 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/conversation.py +264 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/deepseek_vl_v2.py +472 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/language.py +591 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/processing_deepsek_vl_v2.py +526 -0
- nexaai/mlx_backend/vlm/modeling/models/deepseek_vl_v2/vision.py +356 -0
- nexaai/mlx_backend/vlm/modeling/models/florence2/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/florence2/florence2.py +366 -0
- nexaai/mlx_backend/vlm/modeling/models/florence2/language.py +488 -0
- nexaai/mlx_backend/vlm/modeling/models/florence2/vision.py +591 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3/gemma3.py +213 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3/language.py +315 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3/vision.py +238 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/__init__.py +2 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/audio.py +1038 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/config.py +139 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/gemma3n.py +322 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/language.py +629 -0
- nexaai/mlx_backend/vlm/modeling/models/gemma3n/vision.py +1022 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics2/__init__.py +9 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics2/idefics2.py +294 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics2/language.py +191 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics2/vision.py +267 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics3/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics3/idefics3.py +175 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics3/language.py +192 -0
- nexaai/mlx_backend/vlm/modeling/models/idefics3/vision.py +233 -0
- nexaai/mlx_backend/vlm/modeling/models/internvl_chat/__init__.py +9 -0
- nexaai/mlx_backend/vlm/modeling/models/internvl_chat/internvl_chat.py +140 -0
- nexaai/mlx_backend/vlm/modeling/models/internvl_chat/language.py +220 -0
- nexaai/mlx_backend/vlm/modeling/models/internvl_chat/processor.py +393 -0
- nexaai/mlx_backend/vlm/modeling/models/internvl_chat/vision.py +293 -0
- nexaai/mlx_backend/vlm/modeling/models/kernels.py +307 -0
- nexaai/mlx_backend/vlm/modeling/models/kimi_vl/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/kimi_vl/kimi_vl.py +143 -0
- nexaai/mlx_backend/vlm/modeling/models/kimi_vl/language.py +509 -0
- nexaai/mlx_backend/vlm/modeling/models/kimi_vl/vision.py +522 -0
- nexaai/mlx_backend/vlm/modeling/models/llama4/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/llama4/language.py +386 -0
- nexaai/mlx_backend/vlm/modeling/models/llama4/llama4.py +138 -0
- nexaai/mlx_backend/vlm/modeling/models/llama4/vision.py +560 -0
- nexaai/mlx_backend/vlm/modeling/models/llava/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/llava/language.py +240 -0
- nexaai/mlx_backend/vlm/modeling/models/llava/llava.py +153 -0
- nexaai/mlx_backend/vlm/modeling/models/llava/vision.py +259 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_bunny/__init__.py +9 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_bunny/language.py +236 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_bunny/llava_bunny.py +256 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_bunny/vision.py +303 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_next/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_next/language.py +230 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_next/llava_next.py +160 -0
- nexaai/mlx_backend/vlm/modeling/models/llava_next/vision.py +243 -0
- nexaai/mlx_backend/vlm/modeling/models/mistral3/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/mistral3/mistral3.py +283 -0
- nexaai/mlx_backend/vlm/modeling/models/mllama/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/mllama/language.py +416 -0
- nexaai/mlx_backend/vlm/modeling/models/mllama/mllama.py +172 -0
- nexaai/mlx_backend/vlm/modeling/models/mllama/vision.py +499 -0
- nexaai/mlx_backend/vlm/modeling/models/molmo/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/molmo/language.py +243 -0
- nexaai/mlx_backend/vlm/modeling/models/molmo/molmo.py +133 -0
- nexaai/mlx_backend/vlm/modeling/models/molmo/vision.py +465 -0
- nexaai/mlx_backend/vlm/modeling/models/multi_modality/__init__.py +10 -0
- nexaai/mlx_backend/vlm/modeling/models/multi_modality/language.py +230 -0
- nexaai/mlx_backend/vlm/modeling/models/multi_modality/multi_modality.py +385 -0
- nexaai/mlx_backend/vlm/modeling/models/multi_modality/sam.py +557 -0
- nexaai/mlx_backend/vlm/modeling/models/multi_modality/vision.py +526 -0
- nexaai/mlx_backend/vlm/modeling/models/paligemma/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/paligemma/language.py +282 -0
- nexaai/mlx_backend/vlm/modeling/models/paligemma/paligemma.py +160 -0
- nexaai/mlx_backend/vlm/modeling/models/paligemma/vision.py +242 -0
- nexaai/mlx_backend/vlm/modeling/models/phi3_v/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/phi3_v/language.py +21 -0
- nexaai/mlx_backend/vlm/modeling/models/phi3_v/phi3_v.py +243 -0
- nexaai/mlx_backend/vlm/modeling/models/phi3_v/su_rope.py +71 -0
- nexaai/mlx_backend/vlm/modeling/models/phi3_v/vision.py +324 -0
- nexaai/mlx_backend/vlm/modeling/models/pixtral/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/pixtral/language.py +229 -0
- nexaai/mlx_backend/vlm/modeling/models/pixtral/pixtral.py +161 -0
- nexaai/mlx_backend/vlm/modeling/models/pixtral/vision.py +320 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_5_vl/__init__.py +2 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_5_vl/config.py +108 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_5_vl/language.py +490 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_5_vl/qwen2_5_vl.py +168 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_5_vl/vision.py +414 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_vl/__init__.py +2 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_vl/config.py +104 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_vl/language.py +490 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_vl/qwen2_vl.py +167 -0
- nexaai/mlx_backend/vlm/modeling/models/qwen2_vl/vision.py +312 -0
- nexaai/mlx_backend/vlm/modeling/models/smolvlm/__init__.py +8 -0
- nexaai/mlx_backend/vlm/modeling/models/smolvlm/smolvlm.py +62 -0
- nexaai/mlx_backend/vlm/modeling/processing_qwen2_5_vl.py +209 -0
- nexaai/mlx_backend/vlm/modeling/processing_qwen2_vl.py +215 -0
- nexaai/mlx_backend/vlm/modeling/prompt_utils.py +474 -0
- nexaai/mlx_backend/vlm/modeling/sample_utils.py +39 -0
- nexaai/mlx_backend/vlm/modeling/tokenizer_utils.py +344 -0
- nexaai/mlx_backend/vlm/modeling/trainer/__init__.py +9 -0
- nexaai/mlx_backend/vlm/modeling/trainer/lora.py +70 -0
- nexaai/mlx_backend/vlm/modeling/trainer/trainer.py +296 -0
- nexaai/mlx_backend/vlm/modeling/trainer/utils.py +160 -0
- nexaai/mlx_backend/vlm/modeling/utils.py +928 -0
- nexaai/rerank.py +51 -0
- nexaai/rerank_impl/__init__.py +0 -0
- nexaai/rerank_impl/mlx_rerank_impl.py +91 -0
- nexaai/rerank_impl/pybind_rerank_impl.py +42 -0
- nexaai/runtime.py +64 -0
- nexaai/tts.py +70 -0
- nexaai/tts_impl/__init__.py +0 -0
- nexaai/tts_impl/mlx_tts_impl.py +93 -0
- nexaai/tts_impl/pybind_tts_impl.py +42 -0
- nexaai/utils/avatar_fetcher.py +104 -0
- nexaai/utils/decode.py +18 -0
- nexaai/utils/model_manager.py +1195 -0
- nexaai/utils/progress_tracker.py +372 -0
- nexaai/vlm.py +120 -0
- nexaai/vlm_impl/__init__.py +0 -0
- nexaai/vlm_impl/mlx_vlm_impl.py +205 -0
- nexaai/vlm_impl/pybind_vlm_impl.py +228 -0
- nexaai-1.0.4rc10.dist-info/METADATA +26 -0
- nexaai-1.0.4rc10.dist-info/RECORD +519 -0
- nexaai-1.0.4rc10.dist-info/WHEEL +5 -0
- nexaai-1.0.4rc10.dist-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Copyright © Nexa AI
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import sys
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
import mlx.core as mx
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
curr_dir = os.path.dirname(os.path.abspath(__file__))
|
|
22
|
+
from .modeling.nexa_jina_v2 import Model, ModelArgs
|
|
23
|
+
from tokenizers import Tokenizer
|
|
24
|
+
from huggingface_hub import snapshot_download
|
|
25
|
+
|
|
26
|
+
def load_model(model_id):
|
|
27
|
+
"""Initialize and load the Jina V2 model with FP16 weights."""
|
|
28
|
+
# Load configuration from config.json
|
|
29
|
+
if not os.path.exists(f"{curr_dir}/modelfiles/config.json"):
|
|
30
|
+
print(f"📥 Downloading model {model_id}...")
|
|
31
|
+
|
|
32
|
+
# Ensure modelfiles directory exists
|
|
33
|
+
os.makedirs(f"{curr_dir}/modelfiles", exist_ok=True)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
# Download model with progress indication
|
|
37
|
+
snapshot_download(
|
|
38
|
+
repo_id=model_id,
|
|
39
|
+
local_dir=f"{curr_dir}/modelfiles",
|
|
40
|
+
resume_download=True, # Resume partial downloads
|
|
41
|
+
local_dir_use_symlinks=False # Use actual files instead of symlinks
|
|
42
|
+
)
|
|
43
|
+
print("✅ Model download completed!")
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(f"❌ Failed to download model: {e}")
|
|
46
|
+
print("💡 Try: huggingface-cli login (if authentication required)")
|
|
47
|
+
raise
|
|
48
|
+
|
|
49
|
+
with open(f"{curr_dir}/modelfiles/config.json", "r") as f:
|
|
50
|
+
config_dict = json.load(f)
|
|
51
|
+
|
|
52
|
+
# Create ModelArgs from loaded config
|
|
53
|
+
config = ModelArgs(
|
|
54
|
+
model_type=config_dict["model_type"],
|
|
55
|
+
vocab_size=config_dict["vocab_size"],
|
|
56
|
+
hidden_size=config_dict["hidden_size"],
|
|
57
|
+
num_hidden_layers=config_dict["num_hidden_layers"],
|
|
58
|
+
num_attention_heads=config_dict["num_attention_heads"],
|
|
59
|
+
intermediate_size=config_dict["intermediate_size"],
|
|
60
|
+
hidden_act=config_dict["hidden_act"],
|
|
61
|
+
hidden_dropout_prob=config_dict["hidden_dropout_prob"],
|
|
62
|
+
attention_probs_dropout_prob=config_dict["attention_probs_dropout_prob"],
|
|
63
|
+
max_position_embeddings=config_dict["max_position_embeddings"],
|
|
64
|
+
type_vocab_size=config_dict["type_vocab_size"],
|
|
65
|
+
initializer_range=config_dict["initializer_range"],
|
|
66
|
+
layer_norm_eps=config_dict["layer_norm_eps"],
|
|
67
|
+
pad_token_id=config_dict["pad_token_id"],
|
|
68
|
+
position_embedding_type=config_dict["position_embedding_type"],
|
|
69
|
+
use_cache=config_dict["use_cache"],
|
|
70
|
+
classifier_dropout=config_dict["classifier_dropout"],
|
|
71
|
+
feed_forward_type=config_dict["feed_forward_type"],
|
|
72
|
+
emb_pooler=config_dict["emb_pooler"],
|
|
73
|
+
attn_implementation=config_dict["attn_implementation"],
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Initialize model
|
|
77
|
+
model = Model(config)
|
|
78
|
+
|
|
79
|
+
# Load FP16 weights
|
|
80
|
+
model.load_weights(f"{curr_dir}/modelfiles/model.safetensors", strict=True)
|
|
81
|
+
model.eval()
|
|
82
|
+
|
|
83
|
+
return model
|
|
84
|
+
|
|
85
|
+
def load_tokenizer():
|
|
86
|
+
"""Load and configure the tokenizer."""
|
|
87
|
+
tokenizer = Tokenizer.from_file(f"{curr_dir}/modelfiles/tokenizer.json")
|
|
88
|
+
tokenizer.enable_padding(pad_id=0, pad_token="[PAD]")
|
|
89
|
+
tokenizer.enable_truncation(max_length=512)
|
|
90
|
+
return tokenizer
|
|
91
|
+
|
|
92
|
+
def encode_text(model, tokenizer, text):
|
|
93
|
+
"""Encode a single text and return its embedding."""
|
|
94
|
+
# Tokenize the text
|
|
95
|
+
encoding = tokenizer.encode(text)
|
|
96
|
+
|
|
97
|
+
# Prepare inputs
|
|
98
|
+
input_ids = np.array([encoding.ids], dtype=np.int32)
|
|
99
|
+
attention_mask = np.array([encoding.attention_mask], dtype=np.float32)
|
|
100
|
+
token_type_ids = np.array([encoding.type_ids if encoding.type_ids else [0] * len(encoding.ids)], dtype=np.int32)
|
|
101
|
+
|
|
102
|
+
# Convert to MLX arrays
|
|
103
|
+
input_ids = mx.array(input_ids)
|
|
104
|
+
attention_mask = mx.array(attention_mask)
|
|
105
|
+
token_type_ids = mx.array(token_type_ids)
|
|
106
|
+
|
|
107
|
+
# Get embeddings
|
|
108
|
+
embeddings = model.encode(
|
|
109
|
+
input_ids=input_ids,
|
|
110
|
+
attention_mask=attention_mask,
|
|
111
|
+
token_type_ids=token_type_ids,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return embeddings
|
|
115
|
+
|
|
116
|
+
def main(model_id):
|
|
117
|
+
"""Main function to handle user input and generate embeddings."""
|
|
118
|
+
|
|
119
|
+
# Load model and tokenizer
|
|
120
|
+
model = load_model(model_id)
|
|
121
|
+
tokenizer = load_tokenizer()
|
|
122
|
+
user_input = "Hello, how are you?"
|
|
123
|
+
embedding = encode_text(model, tokenizer, user_input)
|
|
124
|
+
print(f"Embedding shape: {embedding.shape}")
|
|
125
|
+
print(f"Embedding sample values: {embedding.flatten()[:5].tolist()}")
|
|
126
|
+
print(f"Embedding min: {embedding.min()}, Max: {embedding.max()}, Mean: {embedding.mean()}, Std: {embedding.std()}")
|
|
127
|
+
|
|
128
|
+
if __name__ == "__main__":
|
|
129
|
+
model_id = "nexaml/jina-v2-fp16-mlx"
|
|
130
|
+
main(model_id)
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Copyright © Nexa AI
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import json
|
|
19
|
+
import mlx.core as mx
|
|
20
|
+
import numpy as np
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any, List, Optional, Sequence
|
|
23
|
+
|
|
24
|
+
# Import necessary modules
|
|
25
|
+
from tokenizers import Tokenizer
|
|
26
|
+
|
|
27
|
+
# Import from ml.py for API alignment
|
|
28
|
+
from ml import (
|
|
29
|
+
Embedder as BaseEmbedder,
|
|
30
|
+
EmbeddingConfig,
|
|
31
|
+
Path as PathType,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Import profiling module
|
|
35
|
+
from profiling import ProfilingMixin, StopReason
|
|
36
|
+
|
|
37
|
+
# Import the model implementation
|
|
38
|
+
from .modeling.nexa_jina_v2 import Model, ModelArgs
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Embedder(BaseEmbedder, ProfilingMixin):
|
|
42
|
+
"""
|
|
43
|
+
Embedder interface for MLX embedding models.
|
|
44
|
+
API aligned with ml.py Embedder abstract base class.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
model_path: PathType,
|
|
50
|
+
tokenizer_path: PathType,
|
|
51
|
+
device: Optional[str] = None,
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Initialize the Embedder model."""
|
|
54
|
+
# Initialize profiling mixin
|
|
55
|
+
ProfilingMixin.__init__(self)
|
|
56
|
+
|
|
57
|
+
# Store paths
|
|
58
|
+
if (os.path.isfile(model_path)):
|
|
59
|
+
model_path = os.path.dirname(model_path)
|
|
60
|
+
|
|
61
|
+
# Call parent constructor
|
|
62
|
+
# MLX manages device automatically, so we pass None for device
|
|
63
|
+
super().__init__(model_path, tokenizer_path, device)
|
|
64
|
+
|
|
65
|
+
self.model_path = model_path
|
|
66
|
+
self.tokenizer_path = tokenizer_path
|
|
67
|
+
self.device = device if device is not None else "cpu" # TODO: This device field is never used
|
|
68
|
+
|
|
69
|
+
# Initialize model and tokenizer as None
|
|
70
|
+
self.model = None
|
|
71
|
+
self.tokenizer = None
|
|
72
|
+
self.config = None
|
|
73
|
+
|
|
74
|
+
def destroy(self) -> None:
|
|
75
|
+
"""Destroy the model and free resources."""
|
|
76
|
+
self.model = None
|
|
77
|
+
self.tokenizer = None
|
|
78
|
+
self.config = None
|
|
79
|
+
self.reset_profiling()
|
|
80
|
+
|
|
81
|
+
def load_model(self, model_path: PathType) -> bool:
|
|
82
|
+
"""Load model from path."""
|
|
83
|
+
try:
|
|
84
|
+
# Use the provided model_path or fall back to instance path
|
|
85
|
+
if model_path:
|
|
86
|
+
# Apply same file-to-directory conversion as in __init__
|
|
87
|
+
if os.path.isfile(model_path):
|
|
88
|
+
model_path = os.path.dirname(model_path)
|
|
89
|
+
self.model_path = model_path
|
|
90
|
+
|
|
91
|
+
# Load the model using internal implementation
|
|
92
|
+
self.model = self._load_jina_model(self.model_path)
|
|
93
|
+
self.tokenizer = self._load_tokenizer()
|
|
94
|
+
|
|
95
|
+
return True
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(f"Failed to load model: {e}")
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
def close(self) -> None:
|
|
101
|
+
"""Close the model."""
|
|
102
|
+
self.destroy()
|
|
103
|
+
|
|
104
|
+
def embed(
|
|
105
|
+
self,
|
|
106
|
+
texts: Sequence[str],
|
|
107
|
+
config: Optional[EmbeddingConfig] = None,
|
|
108
|
+
clear_cache: bool = True,
|
|
109
|
+
) -> List[List[float]]:
|
|
110
|
+
"""Generate embeddings for texts."""
|
|
111
|
+
if self.model is None or self.tokenizer is None:
|
|
112
|
+
raise RuntimeError("Model not loaded. Call load_model() first.")
|
|
113
|
+
|
|
114
|
+
if config is None:
|
|
115
|
+
config = EmbeddingConfig()
|
|
116
|
+
|
|
117
|
+
# Start profiling
|
|
118
|
+
self._start_profiling()
|
|
119
|
+
|
|
120
|
+
# Calculate total tokens for all texts
|
|
121
|
+
total_tokens = sum(len(self.tokenizer.encode(text).ids) for text in texts)
|
|
122
|
+
self._update_prompt_tokens(total_tokens)
|
|
123
|
+
|
|
124
|
+
# End prompt processing, start decode
|
|
125
|
+
self._prompt_end()
|
|
126
|
+
self._decode_start()
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
embeddings = []
|
|
130
|
+
|
|
131
|
+
# Process texts in batches
|
|
132
|
+
batch_size = config.batch_size
|
|
133
|
+
for i in range(0, len(texts), batch_size):
|
|
134
|
+
batch_texts = texts[i:i + batch_size]
|
|
135
|
+
batch_embeddings = self._encode_batch(batch_texts, config)
|
|
136
|
+
embeddings.extend(batch_embeddings)
|
|
137
|
+
|
|
138
|
+
if clear_cache:
|
|
139
|
+
mx.clear_cache()
|
|
140
|
+
|
|
141
|
+
# End timing and finalize profiling data
|
|
142
|
+
self._update_generated_tokens(0) # No generation in embedding
|
|
143
|
+
self._set_stop_reason(StopReason.ML_STOP_REASON_COMPLETED)
|
|
144
|
+
self._decode_end()
|
|
145
|
+
self._end_profiling()
|
|
146
|
+
|
|
147
|
+
return embeddings
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
self._set_stop_reason(StopReason.ML_STOP_REASON_UNKNOWN)
|
|
151
|
+
self._decode_end()
|
|
152
|
+
self._end_profiling()
|
|
153
|
+
raise RuntimeError(f"Error generating embeddings: {str(e)}")
|
|
154
|
+
|
|
155
|
+
def embedding_dim(self) -> int:
|
|
156
|
+
"""Get embedding dimension."""
|
|
157
|
+
if self.config is None:
|
|
158
|
+
return 768 # Default dimension for Jina v2
|
|
159
|
+
return self.config.hidden_size
|
|
160
|
+
|
|
161
|
+
def set_lora(self, lora_id: int) -> None:
|
|
162
|
+
"""Set active LoRA adapter. (Disabled for embedding models)"""
|
|
163
|
+
raise NotImplementedError("LoRA is not supported for embedding models")
|
|
164
|
+
|
|
165
|
+
def add_lora(self, lora_path: PathType) -> int:
|
|
166
|
+
"""Add LoRA adapter and return its ID. (Disabled for embedding models)"""
|
|
167
|
+
raise NotImplementedError("LoRA is not supported for embedding models")
|
|
168
|
+
|
|
169
|
+
def remove_lora(self, lora_id: int) -> None:
|
|
170
|
+
"""Remove LoRA adapter. (Disabled for embedding models)"""
|
|
171
|
+
raise NotImplementedError("LoRA is not supported for embedding models")
|
|
172
|
+
|
|
173
|
+
def list_loras(self) -> List[int]:
|
|
174
|
+
"""List available LoRA adapters. (Disabled for embedding models)"""
|
|
175
|
+
raise NotImplementedError("LoRA is not supported for embedding models")
|
|
176
|
+
|
|
177
|
+
def _load_jina_model(self, model_dir: str) -> Model:
|
|
178
|
+
"""Initialize and load the Jina V2 model with FP16 weights."""
|
|
179
|
+
|
|
180
|
+
# Validate that model path exists
|
|
181
|
+
if not os.path.exists(model_dir):
|
|
182
|
+
raise ValueError(f"Model path does not exist: {model_dir}")
|
|
183
|
+
|
|
184
|
+
print(f"Using local model path: {model_dir}")
|
|
185
|
+
config_path = os.path.join(model_dir, "config.json")
|
|
186
|
+
|
|
187
|
+
if not os.path.exists(config_path):
|
|
188
|
+
raise FileNotFoundError(f"Config file not found: {config_path}")
|
|
189
|
+
|
|
190
|
+
with open(config_path, "r") as f:
|
|
191
|
+
config_dict = json.load(f)
|
|
192
|
+
|
|
193
|
+
# Create ModelArgs from loaded config
|
|
194
|
+
config = ModelArgs(
|
|
195
|
+
model_type=config_dict["model_type"],
|
|
196
|
+
vocab_size=config_dict["vocab_size"],
|
|
197
|
+
hidden_size=config_dict["hidden_size"],
|
|
198
|
+
num_hidden_layers=config_dict["num_hidden_layers"],
|
|
199
|
+
num_attention_heads=config_dict["num_attention_heads"],
|
|
200
|
+
intermediate_size=config_dict["intermediate_size"],
|
|
201
|
+
hidden_act=config_dict["hidden_act"],
|
|
202
|
+
hidden_dropout_prob=config_dict["hidden_dropout_prob"],
|
|
203
|
+
attention_probs_dropout_prob=config_dict["attention_probs_dropout_prob"],
|
|
204
|
+
max_position_embeddings=config_dict["max_position_embeddings"],
|
|
205
|
+
type_vocab_size=config_dict["type_vocab_size"],
|
|
206
|
+
initializer_range=config_dict["initializer_range"],
|
|
207
|
+
layer_norm_eps=config_dict["layer_norm_eps"],
|
|
208
|
+
pad_token_id=config_dict["pad_token_id"],
|
|
209
|
+
position_embedding_type=config_dict["position_embedding_type"],
|
|
210
|
+
use_cache=config_dict["use_cache"],
|
|
211
|
+
classifier_dropout=config_dict["classifier_dropout"],
|
|
212
|
+
feed_forward_type=config_dict["feed_forward_type"],
|
|
213
|
+
emb_pooler=config_dict["emb_pooler"],
|
|
214
|
+
attn_implementation=config_dict["attn_implementation"],
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Store config for embedding_dim()
|
|
218
|
+
self.config = config
|
|
219
|
+
|
|
220
|
+
# Initialize model
|
|
221
|
+
model = Model(config)
|
|
222
|
+
|
|
223
|
+
# Load FP16 weights from model path
|
|
224
|
+
weights_path = os.path.join(model_dir, "model.safetensors")
|
|
225
|
+
self._model_dir = model_dir
|
|
226
|
+
|
|
227
|
+
# Validate that weights file exists
|
|
228
|
+
if not os.path.exists(weights_path):
|
|
229
|
+
raise FileNotFoundError(f"Model weights file not found: {weights_path}")
|
|
230
|
+
|
|
231
|
+
model.load_weights(weights_path, strict=True)
|
|
232
|
+
model.eval()
|
|
233
|
+
|
|
234
|
+
return model
|
|
235
|
+
|
|
236
|
+
def _load_tokenizer(self) -> Tokenizer:
|
|
237
|
+
"""Load and configure the tokenizer."""
|
|
238
|
+
tokenizer_path = os.path.join(self._model_dir, "tokenizer.json")
|
|
239
|
+
tokenizer = Tokenizer.from_file(tokenizer_path)
|
|
240
|
+
tokenizer.enable_padding(pad_id=0, pad_token="[PAD]")
|
|
241
|
+
tokenizer.enable_truncation(max_length=512)
|
|
242
|
+
return tokenizer
|
|
243
|
+
|
|
244
|
+
def _encode_batch(self, texts: List[str], config: EmbeddingConfig) -> List[List[float]]:
|
|
245
|
+
"""Encode a batch of texts and return their embeddings."""
|
|
246
|
+
embeddings = []
|
|
247
|
+
|
|
248
|
+
for text in texts:
|
|
249
|
+
embedding = self._encode_single_text(text, config)
|
|
250
|
+
embeddings.append(embedding)
|
|
251
|
+
|
|
252
|
+
return embeddings
|
|
253
|
+
|
|
254
|
+
def _encode_single_text(self, text: str, config: EmbeddingConfig) -> List[float]:
|
|
255
|
+
"""Encode a single text and return its embedding."""
|
|
256
|
+
# Tokenize the text
|
|
257
|
+
encoding = self.tokenizer.encode(text)
|
|
258
|
+
|
|
259
|
+
# Prepare inputs
|
|
260
|
+
input_ids = np.array([encoding.ids], dtype=np.int32)
|
|
261
|
+
attention_mask = np.array([encoding.attention_mask], dtype=np.float32)
|
|
262
|
+
token_type_ids = np.array([encoding.type_ids if encoding.type_ids else [0] * len(encoding.ids)], dtype=np.int32)
|
|
263
|
+
|
|
264
|
+
# Convert to MLX arrays
|
|
265
|
+
input_ids = mx.array(input_ids)
|
|
266
|
+
attention_mask = mx.array(attention_mask)
|
|
267
|
+
token_type_ids = mx.array(token_type_ids)
|
|
268
|
+
|
|
269
|
+
# Get embeddings
|
|
270
|
+
embeddings = self.model.encode(
|
|
271
|
+
input_ids=input_ids,
|
|
272
|
+
attention_mask=attention_mask,
|
|
273
|
+
token_type_ids=token_type_ids,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Convert to list and apply normalization if requested
|
|
277
|
+
embedding_list = embeddings.flatten().tolist()
|
|
278
|
+
|
|
279
|
+
if config.normalize:
|
|
280
|
+
embedding_list = self._normalize_embedding(embedding_list, config.normalize_method)
|
|
281
|
+
|
|
282
|
+
return embedding_list
|
|
283
|
+
|
|
284
|
+
def _normalize_embedding(self, embedding: List[float], method: str) -> List[float]:
|
|
285
|
+
"""Normalize embedding using specified method."""
|
|
286
|
+
if method == "none":
|
|
287
|
+
return embedding
|
|
288
|
+
|
|
289
|
+
embedding_array = np.array(embedding)
|
|
290
|
+
|
|
291
|
+
if method == "l2":
|
|
292
|
+
norm = np.linalg.norm(embedding_array)
|
|
293
|
+
if norm > 0:
|
|
294
|
+
embedding_array = embedding_array / norm
|
|
295
|
+
elif method == "mean":
|
|
296
|
+
mean_val = np.mean(embedding_array)
|
|
297
|
+
embedding_array = embedding_array - mean_val
|
|
298
|
+
|
|
299
|
+
return embedding_array.tolist()
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# Factory function for creating embedder instances
|
|
303
|
+
def create_embedder(
|
|
304
|
+
model_path: PathType,
|
|
305
|
+
tokenizer_path: Optional[PathType] = None,
|
|
306
|
+
device: Optional[str] = None,
|
|
307
|
+
) -> Embedder:
|
|
308
|
+
"""Create and return an Embedder instance."""
|
|
309
|
+
if tokenizer_path is None:
|
|
310
|
+
tokenizer_path = model_path
|
|
311
|
+
|
|
312
|
+
return Embedder(model_path, tokenizer_path, device)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Copyright © Nexa AI
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from .interface import create_embedder, EmbeddingConfig
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_embedding(model_path):
|
|
19
|
+
"""Test embedding model functionality."""
|
|
20
|
+
embedder = create_embedder(model_path=model_path)
|
|
21
|
+
|
|
22
|
+
# Load the model
|
|
23
|
+
print("Loading embedding model...")
|
|
24
|
+
success = embedder.load_model(model_path)
|
|
25
|
+
|
|
26
|
+
if not success:
|
|
27
|
+
print("Failed to load model!")
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
print("✅ Model loaded successfully!")
|
|
31
|
+
print(f"Embedding dimension: {embedder.embedding_dim()}")
|
|
32
|
+
|
|
33
|
+
# Test texts
|
|
34
|
+
test_texts = [
|
|
35
|
+
"Hello, how are you?",
|
|
36
|
+
"What is machine learning?",
|
|
37
|
+
"The weather is nice today.",
|
|
38
|
+
"Python is a programming language."
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
# Configure embedding
|
|
42
|
+
config = EmbeddingConfig(
|
|
43
|
+
batch_size=2,
|
|
44
|
+
normalize=True,
|
|
45
|
+
normalize_method="l2"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
print(f"\nGenerating embeddings for {len(test_texts)} texts...")
|
|
49
|
+
|
|
50
|
+
# Generate embeddings
|
|
51
|
+
embeddings = embedder.embed(test_texts, config)
|
|
52
|
+
|
|
53
|
+
# Display results
|
|
54
|
+
print("\nEmbedding Results:")
|
|
55
|
+
print("=" * 50)
|
|
56
|
+
|
|
57
|
+
for i, (text, embedding) in enumerate(zip(test_texts, embeddings)):
|
|
58
|
+
print(f"\nText {i+1}: '{text}'")
|
|
59
|
+
print(f"Embedding shape: {len(embedding)}")
|
|
60
|
+
print(f"First 5 values: {embedding[:5]}")
|
|
61
|
+
|
|
62
|
+
# Calculate magnitude for normalized embeddings
|
|
63
|
+
magnitude = sum(x*x for x in embedding) ** 0.5
|
|
64
|
+
print(f"Magnitude: {magnitude:.6f}")
|
|
65
|
+
|
|
66
|
+
# Test similarity between first two embeddings
|
|
67
|
+
if len(embeddings) >= 2:
|
|
68
|
+
emb1, emb2 = embeddings[0], embeddings[1]
|
|
69
|
+
similarity = sum(a*b for a, b in zip(emb1, emb2))
|
|
70
|
+
print(f"\nCosine similarity between text 1 and 2: {similarity:.6f}")
|
|
71
|
+
|
|
72
|
+
# Cleanup
|
|
73
|
+
embedder.close()
|
|
74
|
+
print("\n✅ Embedding test completed!")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
import argparse
|
|
79
|
+
parser = argparse.ArgumentParser()
|
|
80
|
+
parser.add_argument("--model_path", type=str, default="nexaml/jina-v2-fp16-mlx")
|
|
81
|
+
args = parser.parse_args()
|
|
82
|
+
test_embedding(args.model_path)
|
|
File without changes
|