yongqiang commited on
Commit ·
eec42a1
1
Parent(s): a2cbb72
Add 8s audio profile for Jina nano retrieval
Browse files- .gitignore +1 -0
- README.md +26 -10
- assets/audio_test_chunk0_8s.wav +3 -0
- bin/axllm +2 -2
- config.json +2 -1
- jina_v5_omni_nano_audio_8s.axmodel +3 -0
- python/compare_openai_api_vs_hf_multimodal.py +4 -2
- python/jina_omni_utils.py +4 -0
- python/testdata/service_cases/audio_test_chunk0_8s_wav/meta.json +10 -0
- python/testdata/service_cases/audio_test_chunk0_8s_wav/torch_embedding.npy +3 -0
.gitignore
CHANGED
|
@@ -3,6 +3,7 @@ __pycache__/
|
|
| 3 |
vision_cache/
|
| 4 |
*.tmp
|
| 5 |
tmp/
|
|
|
|
| 6 |
WORKFLOW.md
|
| 7 |
model.embed_tokens.weight.npy
|
| 8 |
serve_*.log
|
|
|
|
| 3 |
vision_cache/
|
| 4 |
*.tmp
|
| 5 |
tmp/
|
| 6 |
+
tmp_baiyongqiang/
|
| 7 |
WORKFLOW.md
|
| 8 |
model.embed_tokens.weight.npy
|
| 9 |
serve_*.log
|
README.md
CHANGED
|
@@ -26,22 +26,31 @@ It was rebuilt with the correct text RoPE base and passes the packaged text, ima
|
|
| 26 |
- Current service model id: `AXERA-TECH/jina-embeddings-v5-omni-nano-retrieval-AX650-P128-CTX2047`
|
| 27 |
- Vision encoder static shape: `256x256`
|
| 28 |
- Vision soft tokens per frame: `64`
|
| 29 |
-
- Audio encoder static
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
- Current LLM prefill build:
|
| 31 |
- `prefill_len = 128`
|
| 32 |
- warm-prefill groups = `128 / 256 / 384 / 512 / 640 / 768 / 896`
|
| 33 |
- effective `prefill_max_token_num = 1024`
|
| 34 |
|
| 35 |
-
Board cold-start measurements from this package:
|
| 36 |
|
| 37 |
| Item | Value |
|
| 38 |
|---|---:|
|
| 39 |
-
| `/
|
| 40 |
-
| CMM
|
| 41 |
-
| CMM
|
| 42 |
-
| Cold-start CMM consumption | `
|
| 43 |
-
| Process
|
| 44 |
-
| Process
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
## Functional Status
|
| 47 |
|
|
@@ -58,6 +67,7 @@ The packaged runtime files are:
|
|
| 58 |
- `llama_p128_l0_together.axmodel` ... `llama_p128_l11_together.axmodel`
|
| 59 |
- `llama_post.axmodel`
|
| 60 |
- `jina_v5_omni_nano_vision_256x256.axmodel`
|
|
|
|
| 61 |
- `jina_v5_omni_nano_audio_30s.axmodel`
|
| 62 |
- `model.embed_tokens.weight.bfloat16.bin`
|
| 63 |
- `jina_v5_omni_tokenizer.txt`
|
|
@@ -103,8 +113,9 @@ Current board-side `axllm serve` precision against the packaged Hugging Face ref
|
|
| 103 |
| Text | `embedding_doc` | `[1, 768]` | `0.999655` |
|
| 104 |
| Text | `red_planet_query` | `[1, 768]` | `0.999539` |
|
| 105 |
| Image | `vision_sample` | `[1, 768]` | `0.993549` |
|
|
|
|
| 106 |
| Audio | `audio_test_chunk0_30s_wav` | `[1, 768]` | `0.994962` |
|
| 107 |
-
| Video | `video_visual_red_panda_openai_mp4` | `[1, 768]` | `0.
|
| 108 |
|
| 109 |
Key observations:
|
| 110 |
|
|
@@ -112,7 +123,9 @@ Key observations:
|
|
| 112 |
- The previous `embedding_doc = 0.9604` result was traced to an LLM build config issue, not to the OpenAI-compatible service wrapper.
|
| 113 |
- `jina-embeddings-v5-omni-nano` uses `text_config.rope_parameters.rope_theta = 1000000.0`; the earlier `llama` build path silently fell back to `10000.0`.
|
| 114 |
- The current LLM AXModels were rebuilt after flattening `rope_theta` into `text_config.rope_theta` for `pulsar2 llm_build`.
|
| 115 |
-
- With the corrected RoPE base, all packaged precision cases are in the `0.9935 ~ 0.9997` cosine range.
|
|
|
|
|
|
|
| 116 |
|
| 117 |
## Board Precision Validation Flow
|
| 118 |
|
|
@@ -188,6 +201,7 @@ Current packaged cases:
|
|
| 188 |
- `embedding_doc`
|
| 189 |
- `red_planet_query`
|
| 190 |
- `vision_sample`
|
|
|
|
| 191 |
- `audio_test_chunk0_30s_wav`
|
| 192 |
- `video_visual_red_panda_openai_mp4`
|
| 193 |
|
|
@@ -197,3 +211,5 @@ The packaged `meta.json` files define the exact text, prompt name, media asset p
|
|
| 197 |
## Known Limitation
|
| 198 |
|
| 199 |
- Re-measure direct audio split latency if a low-memory benchmark implementation is needed; the packaged service audio path is already validated.
|
|
|
|
|
|
|
|
|
| 26 |
- Current service model id: `AXERA-TECH/jina-embeddings-v5-omni-nano-retrieval-AX650-P128-CTX2047`
|
| 27 |
- Vision encoder static shape: `256x256`
|
| 28 |
- Vision soft tokens per frame: `64`
|
| 29 |
+
- Audio encoder static profiles:
|
| 30 |
+
- short audio: `8s`, `16kHz`, mono, `800` mel frames, `200` soft tokens
|
| 31 |
+
- long audio: `30s`, `16kHz`, mono, `3000` mel frames, `750` soft tokens
|
| 32 |
+
- Audio request sequence length with the packaged `query` prompt:
|
| 33 |
+
- `8s` audio: `200` soft tokens, about `220` total LLM prefill tokens
|
| 34 |
+
- `30s` audio: `750` soft tokens, about `772` total LLM prefill tokens
|
| 35 |
- Current LLM prefill build:
|
| 36 |
- `prefill_len = 128`
|
| 37 |
- warm-prefill groups = `128 / 256 / 384 / 512 / 640 / 768 / 896`
|
| 38 |
- effective `prefill_max_token_num = 1024`
|
| 39 |
|
| 40 |
+
Board cold-start measurements from this package with both `8s` and `30s` audio profiles loaded:
|
| 41 |
|
| 42 |
| Item | Value |
|
| 43 |
|---|---:|
|
| 44 |
+
| `/v1/models` ready time | `25 s` |
|
| 45 |
+
| CMM used before startup | `275004 KB` |
|
| 46 |
+
| CMM used after startup | `2455548 KB` |
|
| 47 |
+
| Cold-start CMM consumption | `2180544 KB` |
|
| 48 |
+
| Process VmRSS after startup | `2011016 KB` |
|
| 49 |
+
| Process PSS after startup | `2010169 KB` |
|
| 50 |
+
| Process anonymous memory | `2006272 KB` |
|
| 51 |
+
| Process VmSize after startup | `4191272 KB` |
|
| 52 |
+
|
| 53 |
+
`CMM` means AXERA contiguous multimedia memory. `RSS` means resident set size in Linux process memory. `PSS` means proportional set size.
|
| 54 |
|
| 55 |
## Functional Status
|
| 56 |
|
|
|
|
| 67 |
- `llama_p128_l0_together.axmodel` ... `llama_p128_l11_together.axmodel`
|
| 68 |
- `llama_post.axmodel`
|
| 69 |
- `jina_v5_omni_nano_vision_256x256.axmodel`
|
| 70 |
+
- `jina_v5_omni_nano_audio_8s.axmodel`
|
| 71 |
- `jina_v5_omni_nano_audio_30s.axmodel`
|
| 72 |
- `model.embed_tokens.weight.bfloat16.bin`
|
| 73 |
- `jina_v5_omni_tokenizer.txt`
|
|
|
|
| 113 |
| Text | `embedding_doc` | `[1, 768]` | `0.999655` |
|
| 114 |
| Text | `red_planet_query` | `[1, 768]` | `0.999539` |
|
| 115 |
| Image | `vision_sample` | `[1, 768]` | `0.993549` |
|
| 116 |
+
| Audio | `audio_test_chunk0_8s_wav` | `[1, 768]` | `0.989344` |
|
| 117 |
| Audio | `audio_test_chunk0_30s_wav` | `[1, 768]` | `0.994962` |
|
| 118 |
+
| Video | `video_visual_red_panda_openai_mp4` | `[1, 768]` | `0.997008` |
|
| 119 |
|
| 120 |
Key observations:
|
| 121 |
|
|
|
|
| 123 |
- The previous `embedding_doc = 0.9604` result was traced to an LLM build config issue, not to the OpenAI-compatible service wrapper.
|
| 124 |
- `jina-embeddings-v5-omni-nano` uses `text_config.rope_parameters.rope_theta = 1000000.0`; the earlier `llama` build path silently fell back to `10000.0`.
|
| 125 |
- The current LLM AXModels were rebuilt after flattening `rope_theta` into `text_config.rope_theta` for `pulsar2 llm_build`.
|
| 126 |
+
- With the corrected RoPE base, all non-audio-short packaged precision cases are in the `0.9935 ~ 0.9997` cosine range.
|
| 127 |
+
- The `8s` audio profile is usable but lower than the `30s` profile in this P128 build: `0.989344` cosine for the packaged `audio_test_chunk0_8s_wav` case.
|
| 128 |
+
The previous `5s` audio profile produced only about `0.94` cosine after LLM prefill, so it is not used as a default packaged precision case.
|
| 129 |
|
| 130 |
## Board Precision Validation Flow
|
| 131 |
|
|
|
|
| 201 |
- `embedding_doc`
|
| 202 |
- `red_planet_query`
|
| 203 |
- `vision_sample`
|
| 204 |
+
- `audio_test_chunk0_8s_wav`
|
| 205 |
- `audio_test_chunk0_30s_wav`
|
| 206 |
- `video_visual_red_panda_openai_mp4`
|
| 207 |
|
|
|
|
| 211 |
## Known Limitation
|
| 212 |
|
| 213 |
- Re-measure direct audio split latency if a low-memory benchmark implementation is needed; the packaged service audio path is already validated.
|
| 214 |
+
- Audio encoder loading is controlled by `filename_audio_encoder_axmodel_short` and `filename_audio_encoder_axmodel_long` in `config.json`.
|
| 215 |
+
If only one field is configured, only that audio profile is loaded; if both are configured, the runtime selects the short profile for short audio and falls back to the long profile for longer audio.
|
assets/audio_test_chunk0_8s.wav
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cc5f3d6b74a04a49c0fe151b2c3048cf5a519bfbdec78343617b6be1fb67e49d
|
| 3 |
+
size 1411244
|
bin/axllm
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f44e9785c1ae345fd6d77bee694fdfe4e541f719a7a68eab15ed6d94bef96c39
|
| 3 |
+
size 2397928
|
config.json
CHANGED
|
@@ -16,7 +16,8 @@
|
|
| 16 |
"b_use_mmap_load_layer": true,
|
| 17 |
"vlm_type": "Qwen3Omni",
|
| 18 |
"filename_image_encoder_axmodel": "jina_v5_omni_nano_vision_256x256.axmodel",
|
| 19 |
-
"
|
|
|
|
| 20 |
"vision_width": 256,
|
| 21 |
"vision_height": 256,
|
| 22 |
"vision_patch_size": 16,
|
|
|
|
| 16 |
"b_use_mmap_load_layer": true,
|
| 17 |
"vlm_type": "Qwen3Omni",
|
| 18 |
"filename_image_encoder_axmodel": "jina_v5_omni_nano_vision_256x256.axmodel",
|
| 19 |
+
"filename_audio_encoder_axmodel_short": "jina_v5_omni_nano_audio_8s.axmodel",
|
| 20 |
+
"filename_audio_encoder_axmodel_long": "jina_v5_omni_nano_audio_30s.axmodel",
|
| 21 |
"vision_width": 256,
|
| 22 |
"vision_height": 256,
|
| 23 |
"vision_patch_size": 16,
|
jina_v5_omni_nano_audio_8s.axmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2f00adf09f5bd58e2939ebd6855f79ac2eac0037b4b5cf2e72a1fe8d1a02d519
|
| 3 |
+
size 703218785
|
python/compare_openai_api_vs_hf_multimodal.py
CHANGED
|
@@ -15,14 +15,16 @@ DEFAULT_CASES = (
|
|
| 15 |
("T0", "embedding_doc"),
|
| 16 |
("T1", "red_planet_query"),
|
| 17 |
("A", "vision_sample"),
|
| 18 |
-
("
|
|
|
|
| 19 |
("C", "video_visual_red_panda_openai_mp4"),
|
| 20 |
)
|
| 21 |
CASE_LABEL_NAMES = {
|
| 22 |
"T0": "text_document",
|
| 23 |
"T1": "text_query",
|
| 24 |
"A": "image",
|
| 25 |
-
"
|
|
|
|
| 26 |
"C": "video",
|
| 27 |
}
|
| 28 |
|
|
|
|
| 15 |
("T0", "embedding_doc"),
|
| 16 |
("T1", "red_planet_query"),
|
| 17 |
("A", "vision_sample"),
|
| 18 |
+
("B8", "audio_test_chunk0_8s_wav"),
|
| 19 |
+
("B30", "audio_test_chunk0_30s_wav"),
|
| 20 |
("C", "video_visual_red_panda_openai_mp4"),
|
| 21 |
)
|
| 22 |
CASE_LABEL_NAMES = {
|
| 23 |
"T0": "text_document",
|
| 24 |
"T1": "text_query",
|
| 25 |
"A": "image",
|
| 26 |
+
"B8": "audio_8s",
|
| 27 |
+
"B30": "audio_30s",
|
| 28 |
"C": "video",
|
| 29 |
}
|
| 30 |
|
python/jina_omni_utils.py
CHANGED
|
@@ -370,11 +370,13 @@ def prepare_fixed_audio_inputs(
|
|
| 370 |
|
| 371 |
audio = load_audio_array(audio_path)
|
| 372 |
feat_ext = WhisperFeatureExtractor(feature_size=128)
|
|
|
|
| 373 |
audio_inputs = feat_ext(
|
| 374 |
audio,
|
| 375 |
sampling_rate=16000,
|
| 376 |
return_tensors="pt",
|
| 377 |
padding="max_length",
|
|
|
|
| 378 |
return_attention_mask=True,
|
| 379 |
)
|
| 380 |
input_features = audio_inputs["input_features"]
|
|
@@ -611,6 +613,7 @@ def run_audio_embedding(
|
|
| 611 |
dtype_name: str = "bfloat16",
|
| 612 |
device: str | None = None,
|
| 613 |
truncate_dim: int | None = None,
|
|
|
|
| 614 |
):
|
| 615 |
model_dir = Path(model_dir)
|
| 616 |
model = load_base_model(model_dir, modality="audio", task=task, dtype_name=dtype_name, device=device)
|
|
@@ -620,6 +623,7 @@ def run_audio_embedding(
|
|
| 620 |
model_dir,
|
| 621 |
audio_path=audio_path,
|
| 622 |
prompt_name=prompt_name,
|
|
|
|
| 623 |
processor=processor,
|
| 624 |
tokenizer=tokenizer,
|
| 625 |
config=model.config,
|
|
|
|
| 370 |
|
| 371 |
audio = load_audio_array(audio_path)
|
| 372 |
feat_ext = WhisperFeatureExtractor(feature_size=128)
|
| 373 |
+
max_samples = int(max_frames) * int(feat_ext.hop_length)
|
| 374 |
audio_inputs = feat_ext(
|
| 375 |
audio,
|
| 376 |
sampling_rate=16000,
|
| 377 |
return_tensors="pt",
|
| 378 |
padding="max_length",
|
| 379 |
+
max_length=max_samples,
|
| 380 |
return_attention_mask=True,
|
| 381 |
)
|
| 382 |
input_features = audio_inputs["input_features"]
|
|
|
|
| 613 |
dtype_name: str = "bfloat16",
|
| 614 |
device: str | None = None,
|
| 615 |
truncate_dim: int | None = None,
|
| 616 |
+
max_frames: int = 3000,
|
| 617 |
):
|
| 618 |
model_dir = Path(model_dir)
|
| 619 |
model = load_base_model(model_dir, modality="audio", task=task, dtype_name=dtype_name, device=device)
|
|
|
|
| 623 |
model_dir,
|
| 624 |
audio_path=audio_path,
|
| 625 |
prompt_name=prompt_name,
|
| 626 |
+
max_frames=max_frames,
|
| 627 |
processor=processor,
|
| 628 |
tokenizer=tokenizer,
|
| 629 |
config=model.config,
|
python/testdata/service_cases/audio_test_chunk0_8s_wav/meta.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"case_name": "audio_test_chunk0_8s_wav",
|
| 3 |
+
"modality": "audio",
|
| 4 |
+
"prompt_name": "query",
|
| 5 |
+
"text_prefix": "",
|
| 6 |
+
"asset_path": "assets/audio_test_chunk0_8s.wav",
|
| 7 |
+
"soft_token_count": 200,
|
| 8 |
+
"audio_profile": "8s",
|
| 9 |
+
"feature_frames": 800
|
| 10 |
+
}
|
python/testdata/service_cases/audio_test_chunk0_8s_wav/torch_embedding.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:29839fe4000c35de3a0463292a46e8550ab918cbf638b6834c02f574c94035b8
|
| 3 |
+
size 3200
|