go-whisper-api/whisper/model_pool.go
admin b5c083e06f
Some checks failed
CodeQL / Analyze (go) (push) Successful in 6m28s
Docker Image / build-docker (push) Failing after 13m26s
Lint and Testing / lint (push) Successful in 11m17s
Lint and Testing / test (push) Successful in 11m17s
Lint and Testing / golangci (push) Successful in 2m40s
first commit
2026-06-04 18:10:52 +07:00

90 lines
2.1 KiB
Go

package whisper
import (
"sync"
"go-whisper-api/config"
"github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper"
)
// Model is a loaded whisper.cpp weights file (re-export for API callers).
type Model = whisper.Model
// ModelPool keeps whisper models loaded in memory and serializes inference per model path.
type ModelPool struct {
mu sync.Mutex
entries map[string]*pooledModel
}
type pooledModel struct {
model whisper.Model
mu sync.Mutex
}
func NewModelPool() *ModelPool {
return &ModelPool{entries: make(map[string]*pooledModel)}
}
func (p *ModelPool) WithModel(path string, fn func(whisper.Model) error) error {
e, err := p.entry(path)
if err != nil {
return err
}
e.mu.Lock()
defer e.mu.Unlock()
return fn(e.model)
}
func (p *ModelPool) entry(path string) (*pooledModel, error) {
p.mu.Lock()
defer p.mu.Unlock()
if e, ok := p.entries[path]; ok {
return e, nil
}
m, err := whisper.New(path)
if err != nil {
return nil, err
}
e := &pooledModel{model: m}
p.entries[path] = e
return e, nil
}
func (p *ModelPool) Close() {
p.mu.Lock()
defer p.mu.Unlock()
for _, e := range p.entries {
_ = e.model.Close()
}
p.entries = make(map[string]*pooledModel)
}
var defaultPool = NewModelPool()
func DefaultPool() *ModelPool {
return defaultPool
}
// Transcribe runs speech recognition using a cached model.
func Transcribe(cfg *config.Whisper) (TranscriptResult, error) {
return TranscribeWithPool(defaultPool, cfg, RunOptions{})
}
func TranscribeWithPool(pool *ModelPool, cfg *config.Whisper, opts RunOptions) (TranscriptResult, error) {
if pool == nil {
pool = defaultPool
}
if err := cfg.Validate(); err != nil {
return TranscriptResult{}, err
}
eng := &Engine{cfg: cfg, runOpts: opts}
err := pool.WithModel(cfg.Model, func(m whisper.Model) error {
return eng.transcribeWithModel(m)
})
if err != nil {
return TranscriptResult{}, err
}
return eng.Result(), nil
}