mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-07 23:07:34 -04:00
fix(transcription): honor model-config language/translate + OpenAI language form field (#10731)
fix(transcription): honor model-config language/translate, add language form field The /v1/audio/transcriptions endpoint read only input.Language / input.Translate from the parsed request, and the request middleware never populates those from a multipart upload -- nor did it read a `language` form field. As a result the model config's parameters.language / parameters.translate (a valid PredictionOptions field under `parameters:`) were silently ignored, and multilingual models like canary defaulted to translating into English even when the YAML set language: ru, translate: false (#10655). Resolve both with clear precedence: the request form field wins, then any language on the parsed request, then the model config default. This also makes the endpoint honor OpenAI's `language` form parameter, which was not read before. Applies to both the streaming and non-streaming paths (the resolved values are built into the shared TranscriptionRequest). Note this ensures the language/translate flags reach the backend; whether a given engine acts on them is up to the backend. Closes #10655 Assisted-by: Claude:claude-opus-4-8 [Claude Code] Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
@@ -33,6 +33,29 @@ import (
|
||||
// @Param stream formData boolean false "stream partial results as SSE"
|
||||
// @Success 200 {object} map[string]string "Response"
|
||||
// @Router /v1/audio/transcriptions [post]
|
||||
// resolveTranscriptionLanguage picks the transcription language. The request
|
||||
// form field (OpenAI's `language` param) wins, then any language carried on the
|
||||
// parsed request, and finally the model config default (parameters.language).
|
||||
func resolveTranscriptionLanguage(formLanguage, requestLanguage, configLanguage string) string {
|
||||
if formLanguage != "" {
|
||||
return formLanguage
|
||||
}
|
||||
if requestLanguage != "" {
|
||||
return requestLanguage
|
||||
}
|
||||
return configLanguage
|
||||
}
|
||||
|
||||
// resolveTranscriptionTranslate picks the translate flag: the request form
|
||||
// field (`translate`, when a valid bool) wins over the model config default
|
||||
// (parameters.translate).
|
||||
func resolveTranscriptionTranslate(formTranslate string, configTranslate bool) bool {
|
||||
if b, err := strconv.ParseBool(formTranslate); err == nil {
|
||||
return b
|
||||
}
|
||||
return configTranslate
|
||||
}
|
||||
|
||||
func TranscriptEndpoint(cl *config.ModelConfigLoader, ml *model.ModelLoader, appConfig *config.ApplicationConfig) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
input, ok := c.Get(middleware.CONTEXT_LOCALS_KEY_LOCALAI_REQUEST).(*schema.OpenAIRequest)
|
||||
@@ -112,10 +135,19 @@ func TranscriptEndpoint(cl *config.ModelConfigLoader, ml *model.ModelLoader, app
|
||||
|
||||
xlog.Debug("Audio file copied", "dst", dst)
|
||||
|
||||
// Language/translate resolve with the request form field taking
|
||||
// precedence over the model config default (parameters.language /
|
||||
// parameters.translate). Previously only the parsed request was read,
|
||||
// which for a multipart upload never carries these, so config-level
|
||||
// settings were silently ignored and multilingual models (e.g. canary)
|
||||
// defaulted to English translation. (#10655)
|
||||
language := resolveTranscriptionLanguage(c.FormValue("language"), input.Language, config.Language)
|
||||
translate := resolveTranscriptionTranslate(c.FormValue("translate"), config.Translate)
|
||||
|
||||
req := backend.TranscriptionRequest{
|
||||
Audio: dst,
|
||||
Language: input.Language,
|
||||
Translate: input.Translate,
|
||||
Language: language,
|
||||
Translate: translate,
|
||||
Diarize: diarize,
|
||||
Prompt: prompt,
|
||||
Temperature: temperature,
|
||||
|
||||
48
core/http/endpoints/openai/transcription_resolve_test.go
Normal file
48
core/http/endpoints/openai/transcription_resolve_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package openai
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Transcription language/translate resolution", func() {
|
||||
Describe("resolveTranscriptionLanguage", func() {
|
||||
It("prefers the request form field over everything", func() {
|
||||
Expect(resolveTranscriptionLanguage("en", "fr", "ru")).To(Equal("en"))
|
||||
})
|
||||
|
||||
It("falls back to the parsed request when the form field is empty", func() {
|
||||
Expect(resolveTranscriptionLanguage("", "fr", "ru")).To(Equal("fr"))
|
||||
})
|
||||
|
||||
It("falls back to the model config default when nothing else is set", func() {
|
||||
// The reporter set parameters.language: ru in the model YAML but sent
|
||||
// no language form field; the config value must be honored. (#10655)
|
||||
Expect(resolveTranscriptionLanguage("", "", "ru")).To(Equal("ru"))
|
||||
})
|
||||
|
||||
It("returns empty when no source provides a language", func() {
|
||||
Expect(resolveTranscriptionLanguage("", "", "")).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("resolveTranscriptionTranslate", func() {
|
||||
It("honors a request form field of true", func() {
|
||||
Expect(resolveTranscriptionTranslate("true", false)).To(BeTrue())
|
||||
})
|
||||
|
||||
It("honors a request form field of false over a config default of true", func() {
|
||||
Expect(resolveTranscriptionTranslate("false", true)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("falls back to the model config default when the form field is absent", func() {
|
||||
// parameters.translate: true in the YAML must be honored when no form
|
||||
// field overrides it.
|
||||
Expect(resolveTranscriptionTranslate("", true)).To(BeTrue())
|
||||
})
|
||||
|
||||
It("defaults to the config value (false) when neither is set", func() {
|
||||
Expect(resolveTranscriptionTranslate("", false)).To(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user