From 2184dae3cbd6b072e4696ed1dac6a306dae793c1 Mon Sep 17 00:00:00 2001 From: LauraGPT <18321252+LauraGPT@users.noreply.github.com> Date: Thu, 10 Sep 2026 11:01:49 +0000 Subject: [PATCH] docs: add tested native Transformers pipeline entry point Signed-off-by: LauraGPT <18321252+LauraGPT@users.noreply.github.com> --- examples/transformers/README.md | 47 +++++++++++++++++++++++++++ tests/test_transformers_quickstart.py | 18 ++++++++++ 2 files changed, 65 insertions(+) diff --git a/examples/transformers/README.md b/examples/transformers/README.md index dc55d7b5..e6cd2971 100644 --- a/examples/transformers/README.md +++ b/examples/transformers/README.md @@ -35,6 +35,53 @@ contains `text` and `reached_eos: true`. No access token is required for this public checkpoint. The model itself also runs through the short, no-clone [Python recipe](https://www.funasr.com/en/docs/native-transformers.html). +## Use the Transformers pipeline API + +After the CPU installation above, this Python example also works without a +repository clone. Explicitly select **`any-to-any`**: it uses the native processor +and the checkpoint's structured transcription chat template. + + +```python +from copy import deepcopy +import torch +from transformers import pipeline + +torch.set_num_threads(4) +transcriber = pipeline( + "any-to-any", + model="FunAudioLLM/Fun-ASR-Nano-2512-hf", + revision="d93b302ee7fd505e1b3576120fc142fc6f7820e1", + device="cpu", dtype=torch.float32, trust_remote_code=False, token=False, +) +messages = [{"role": "user", "content": [ + {"type": "audio", "url": "https://huggingface.co/FunAudioLLM/Fun-ASR-Nano-2512/resolve/272c57b82523ada6fd87095e955f8e29100979ab/example/en.mp3"}, + {"type": "language", "language": "英文"}, +]}] +generation_config = deepcopy(transcriber.model.generation_config) +generation_config.update(max_new_tokens=128, do_sample=False, num_beams=1) +result = transcriber( + text=messages, return_full_text=False, + generate_kwargs={"generation_config": generation_config}, + processor_kwargs={"audio_kwargs": {"sampling_rate": 16000}}, +) +print(result[0]["generated_text"]) +``` + +For a local recording, replace the audio entry with +`{"type": "audio", "path": "recording.wav"}`. In this checkpoint's chat template, +the language field uses `中文`, `英文` or `日文`; the higher-level +`apply_transcription_request` helper additionally accepts ISO codes. +`return_full_text=False` excludes the input conversation from the generated text. + +On Transformers 5.17.0, `pipeline("automatic-speech-recognition", ...)` is a +different processing path: our pinned-checkpoint test fails with a floating-point +token-index error. Do not replace `any-to-any` with that task or rely on automatic +task inference. The example above was checked on the public English sample with +CPU float32; it is not a pipeline GPU/batching, accuracy or capacity evaluation. +The 128-token limit is for this short sample, not a completeness guarantee. Use +the CLI below for explicit audio limits and EOS diagnostics. + ## Your recordings and batches ```bash diff --git a/tests/test_transformers_quickstart.py b/tests/test_transformers_quickstart.py index f04f8fb8..bdd36934 100644 --- a/tests/test_transformers_quickstart.py +++ b/tests/test_transformers_quickstart.py @@ -16,6 +16,24 @@ class NativeExampleTests(unittest.TestCase): + def test_pipeline_recipe_uses_registered_task_and_pinned_public_input(self): + guide = (ROOT / 'examples/transformers/README.md').read_text() + blocks = re.findall(r'\s*```python\n(.*?)```', guide, re.S) + self.assertEqual(len(blocks), 1, 'Missing unique runnable pipeline recipe') + tree = ast.parse(blocks[0]) + calls = [n for n in ast.walk(tree) if isinstance(n, ast.Call)] + factory = next(n for n in calls if isinstance(n.func, ast.Name) and n.func.id == 'pipeline') + self.assertEqual(ast.literal_eval(factory.args[0]), 'any-to-any') + options = {kw.arg: kw.value for kw in factory.keywords} + self.assertEqual(ast.literal_eval(options['model']), native.MODEL_ID) + self.assertEqual(ast.literal_eval(options['revision']), native.REVISION) + self.assertEqual(ast.literal_eval(options['device']), 'cpu') + self.assertIs(ast.literal_eval(options['trust_remote_code']), False) + self.assertIs(ast.literal_eval(options['token']), False) + constants = {n.value for n in ast.walk(tree) if isinstance(n, ast.Constant) and isinstance(n.value, str)} + self.assertIn(f'https://huggingface.co/{native.SAMPLE_MODEL}/resolve/{native.SAMPLE_REVISION}/example/en.mp3', constants) + self.assertIn('automatic-speech-recognition', guide) + def test_runtime_choices_fail_closed_without_silent_cpu_fallback(self): validate = getattr(native, 'validate_runtime', None) self.assertTrue(callable(validate), 'Explicit runtime validation is missing')