Repository navigation
feat(asr): transcribe with a remote OpenAI-compatible server - #4853
Conversation
Add ApiAsrOptions for the ASR and video pipelines: the audio is posted to an /v1/audio/transcriptions endpoint (a Whisper server deployed on its own, or a hosted service) with response_format=verbose_json, and the timed segments become the text items of the document, like with the inline backends. Words are added when word_timestamps is set and the server returns them. Nothing is loaded in the Docling process and FFmpeg is not needed for audio files. As for the API picture description, enable_remote_services=True is required, otherwise the pipeline raises OperationNotAllowed. Tests use a stand-in HTTP server: no model is downloaded. Signed-off-by: Fernando Marino <fernando.marino@cs-soprasteria.com>
|
✅ DCO Check Passed Thanks @fer-marino, all your commits are properly signed off. 🎉 |
Merge Protections🟢 Merge protection satisfied — ready to merge. Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
AI triage (advisory)Checked commit This pull request adds Topic labels added: CI safety: no concern found. A maintainer must still approve CI. 1 related pull request(s) in the same code
The |
There was a problem hiding this comment.
AI first review (advisory): no blocker found
This review covers the full diff at dd2fb63775. It read the code and did not run it.
The PR adds a remote OpenAI-compatible ASR backend. The implementation mirrors the existing ApiVlmOptions / picture-description pattern correctly. requests is already a core dependency. No behavioral regressions are visible in the changed code. The one thing the human reviewer must confirm is that the InlineAsrOptions | ApiAsrOptions union in AsrPipelineOptions and VideoPipelineOptions deserializes correctly from JSON — the two kind Literal values differ, so Pydantic v2 auto-discriminates, but no explicit Discriminator annotation is present. The identical pattern is already used for vlm_options in the same file, so this is consistent with the repo standard.
A maintainer makes the merge decision. This review never approves the pull request.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Adds
ApiAsrOptions: the ASR and video pipelines can send the audio to an OpenAI-compatible/v1/audio/transcriptionsendpoint instead of running Whisper in the Docling process.What changes
pipeline_options_asr_model.py:ApiAsrOptions(url,headers,model,language,initial_prompt,word_timestamps,params,timeout).pipeline_options.py:AsrPipelineOptions.asr_optionsandVideoPipelineOptions.asr_optionsalso accept it.asr_transcriber.py:_ApiAsrModelposts the file and parsesverbose_jsoninto the same conversation items the inline models produce._AsrModelFactory.createtakesenable_remote_servicesand refuses the API backend without it (OperationNotAllowed), like the API picture description.asr_pipeline.py,video_pipeline.py: passenable_remote_servicesto the factory.docs/usage/processing_audio_media.md: new section "Transcribing with a remote Whisper server".tests/test_asr_api.py: 12 tests with a stand-in HTTP server (no model download, so not markedml_asr).Behaviour
multipart/form-datawithresponse_format=verbose_json;model,languageandpromptare sent only when set;timestamp_granularities[]issegmentandwordwithword_timestamps=True;paramsare extra form fields (response_formatcannot be overridden).segmentsfails the conversion with anErrorItemthat says why.Not included: a CLI flag (the CLI selects presets with
--asr-model), speaker labels (not part of the OpenAI API), streaming, the translations endpoint. Happy to add a CLI option if wanted.Issue resolved by this Pull Request:
Resolves #4852
Checklist:
Review evidence:
AsrPipelineOptions(asr_options=...)accepts inline models only; a remote server cannot be used. After:ApiAsrOptionsworks withenable_remote_services=Trueand fails withOperationNotAllowedwithout it.pytest tests/test_asr_api.py: 12 passed. The mock-based ASR tests (test_asr_whisper_s2t.py,test_asr_mlx_whisper.py: 29 passed) andtest_options.py,test_video_pipeline.py,test_video_format_routing.pyshow no change in results.ruff checkandruff format --checkare clean on the changed files.tests/data/audio/sources/sample_10s.mp3: two timed segments,ConversionStatus.SUCCESS, text items withTrackSourcestart and end times.ty, the fullprekhooks, and the ML tests that download models.main):test_backend_docling_json.py::test_local_image_uri_is_embedded_with_enable_local_fetch,test_cli.py::test_cli_convert_remote_works_without_local_model_stack,test_cli_tools.py::test_easyocr_lang_is_forwarded_when_easyocr_is_selected.