Skip to content

Commit 3444bd8

Browse files
committed
Merge branch 'main' of github.com:djthorpe/go-whisper
2 parents 76fd81c + d4b7fdc commit 3444bd8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+570
-570
lines changed

Makefile

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ BUILD_DIR := build
1616

1717
# Build flags
1818
BUILD_MODULE := $(shell cat go.mod | head -1 | cut -d ' ' -f 2)
19-
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/whisper/version.GitSource=${BUILD_MODULE}
20-
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/whisper/version.GitTag=$(shell git describe --tags --always)
21-
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/whisper/version.GitBranch=$(shell git name-rev HEAD --name-only --always)
22-
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/whisper/version.GitHash=$(shell git rev-parse HEAD)
23-
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/whisper/version.GoBuildTime=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
19+
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitSource=${BUILD_MODULE}
20+
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitTag=$(shell git describe --tags --always)
21+
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitBranch=$(shell git name-rev HEAD --name-only --always)
22+
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GitHash=$(shell git rev-parse HEAD)
23+
BUILD_LD_FLAGS += -X $(BUILD_MODULE)/pkg/version.GoBuildTime=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
2424
BUILD_FLAGS = -ldflags "-s -w $(BUILD_LD_FLAGS)"
2525

2626
# If GGML_CUDA is set, then add a cuda tag for the go ${BUILD FLAGS}
@@ -30,7 +30,7 @@ ifeq ($(GGML_CUDA),1)
3030
endif
3131

3232
# Targets
33-
all: whisper
33+
all: whisper api
3434

3535
# Generate the pkg-config files
3636
generate: mkdir go-tidy
@@ -42,6 +42,11 @@ whisper: mkdir generate go-tidy libwhisper libggml
4242
@echo "Building whisper"
4343
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} build ${BUILD_FLAGS} -o ${BUILD_DIR}/whisper ./cmd/whisper
4444

45+
# Make api
46+
api: mkdir go-tidy
47+
@echo "Building api"
48+
@${GO} build ${BUILD_FLAGS} -o ${BUILD_DIR}/api ./cmd/api
49+
4550
# Build docker container
4651
docker: docker-dep submodule
4752
@echo build docker image: ${BUILD_TAG} for ${OS}/${ARCH}
@@ -51,14 +56,16 @@ docker: docker-dep submodule
5156
--build-arg OS=${OS} \
5257
--build-arg SOURCE=${BUILD_MODULE} \
5358
--build-arg VERSION=${VERSION} \
54-
-f etc/Dockerfile.${OS}-${ARCH} .
59+
-f etc/Dockerfile .
5560

5661
# Test whisper bindings
5762
test: generate libwhisper libggml
5863
@echo "Running tests (sys)"
5964
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} test -v ./sys/whisper/...
6065
@echo "Running tests (pkg)"
61-
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} test -v ./pkg/whisper/...
66+
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} test -v ./pkg/...
67+
@echo "Running tests (whisper)"
68+
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} test -v ./
6269

6370
# Build whisper-static-library
6471
libwhisper: submodule

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Speech-to-Text in golang. This is an early development version.
44

5-
* `cmd` contains an OpenAI-API compatible server
5+
* `cmd` contains an OpenAI-API compatible service
66
* `pkg` contains the `whisper` service and client
77
* `sys` contains the `whisper` bindings to the `whisper.cpp` library
88
* `third_party` is a submodule for the whisper.cpp source
@@ -11,6 +11,7 @@ Speech-to-Text in golang. This is an early development version.
1111

1212
(Note: Docker images are not created yet - this is some forward planning!)
1313

14+
You can either run the whisper service as a CLI command or in a docker container.
1415
There are docker images for arm64 and amd64 (Intel). The arm64 image is built for
1516
Jetson GPU support specifically, but it will also run on Raspberry Pi's.
1617

@@ -19,14 +20,15 @@ In order to utilize a NVIDIA GPU, you'll need to install the
1920

2021
A docker volume should be created called "whisper" can be used for storing the Whisper language
2122
models. You can see which models are available to download locally [here](https://huggingface.co/ggerganov/whisper.cpp).
22-
The following command will run the server on port 8080:
23+
24+
The following command will run the server on port 8080 for an NVIDIA GPU:
2325

2426
```bash
2527
docker run \
2628
--name whisper-server --rm \
2729
--runtime nvidia --gpus all \ # When using a NVIDIA GPU
2830
-v whisper:/models -p 8080:8080 -e WHISPER_DATA=/models \
29-
ghcr.io/mutablelogic/go-whisper:latest
31+
ghcr.io/mutablelogic/go-whisper
3032
```
3133

3234
If you include a `-debug` flag at the end, you'll get more verbose output. The API is then
@@ -92,6 +94,10 @@ The following `Makefile` targets can be used:
9294

9395
See all the other targets in the `Makefile` for more information.
9496

97+
## Developing
98+
99+
TODO
100+
95101
## Status
96102

97103
Still in development. See this [issue](https://github.com/mutablelogic/go-whisper/issues/1) for

cmd/api/delete.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
type DeleteCmd struct {
4+
Model string `arg:"" name:"model" help:"Model to delete"`
5+
}
6+
7+
func (cmd *DeleteCmd) Run(ctx *Globals) error {
8+
if err := ctx.client.DeleteModel(ctx.ctx, cmd.Model); err != nil {
9+
return err
10+
}
11+
return nil
12+
}

cmd/api/download.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/djthorpe/go-tablewriter"
7+
)
8+
9+
type DownloadCmd struct {
10+
Model string `arg:"" name:"model" help:"Model to download (must end in .bin)"`
11+
}
12+
13+
func (cmd *DownloadCmd) Run(ctx *Globals) error {
14+
model, err := ctx.client.DownloadModel(ctx.ctx, cmd.Model, func(status string, cur, total int64) {
15+
pct := fmt.Sprintf("%02d%%", int(100*float64(cur)/float64(total)))
16+
ctx.writer.Writeln(pct, status)
17+
})
18+
if err != nil {
19+
return err
20+
}
21+
return ctx.writer.Write(model, tablewriter.OptHeader())
22+
}

cmd/api/main.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"os"
6+
"path/filepath"
7+
"syscall"
8+
9+
// Packages
10+
kong "github.com/alecthomas/kong"
11+
tablewriter "github.com/djthorpe/go-tablewriter"
12+
opt "github.com/mutablelogic/go-client"
13+
ctx "github.com/mutablelogic/go-server/pkg/context"
14+
client "github.com/mutablelogic/go-whisper/pkg/client"
15+
)
16+
17+
////////////////////////////////////////////////////////////////////////////////
18+
// TYPES
19+
20+
type Globals struct {
21+
Url string `name:"url" help:"URL of whisper service (can be set from WHISPER_URL env)" default:"${WHISPER_URL}"`
22+
Debug bool `name:"debug" help:"Enable debug output"`
23+
24+
// Writer, service and context
25+
writer *tablewriter.Writer
26+
client *client.Client
27+
ctx context.Context
28+
}
29+
30+
type CLI struct {
31+
Globals
32+
33+
Ping PingCmd `cmd:"ping" help:"Ping the whisper service"`
34+
Models ModelsCmd `cmd:"models" help:"List models"`
35+
Download DownloadCmd `cmd:"download" help:"Download a model"`
36+
Delete DeleteCmd `cmd:"delete" help:"Delete a model"`
37+
}
38+
39+
////////////////////////////////////////////////////////////////////////////////
40+
// GLOBALS
41+
42+
const (
43+
defaultEndpoint = "http://localhost:8080/api/v1"
44+
)
45+
46+
////////////////////////////////////////////////////////////////////////////////
47+
// MAIN
48+
49+
func main() {
50+
// The name of the executable
51+
name, err := os.Executable()
52+
if err != nil {
53+
panic(err)
54+
} else {
55+
name = filepath.Base(name)
56+
}
57+
58+
// Create a cli parser
59+
cli := CLI{}
60+
cmd := kong.Parse(&cli,
61+
kong.Name(name),
62+
kong.Description("speech transcription and translation service client"),
63+
kong.UsageOnError(),
64+
kong.ConfigureHelp(kong.HelpOptions{Compact: true}),
65+
kong.Vars{
66+
"WHISPER_URL": envOrDefault("WHISPER_URL", defaultEndpoint),
67+
},
68+
)
69+
70+
// Set whisper client options
71+
opts := []opt.ClientOpt{}
72+
if cli.Globals.Debug {
73+
opts = append(opts, opt.OptTrace(os.Stderr, true))
74+
}
75+
76+
// Create a whisper client
77+
client, err := client.New(cli.Globals.Url, opts...)
78+
if err != nil {
79+
cmd.FatalIfErrorf(err)
80+
return
81+
} else {
82+
cli.Globals.client = client
83+
}
84+
85+
// Create a tablewriter object with text output
86+
writer := tablewriter.New(os.Stdout, tablewriter.OptOutputText())
87+
cli.Globals.writer = writer
88+
89+
// Create a context
90+
cli.Globals.ctx = ctx.ContextForSignal(os.Interrupt, syscall.SIGQUIT)
91+
92+
// Run the command
93+
if err := cmd.Run(&cli.Globals); err != nil {
94+
cmd.FatalIfErrorf(err)
95+
}
96+
}
97+
98+
func envOrDefault(name, def string) string {
99+
if value := os.Getenv(name); value != "" {
100+
return value
101+
} else {
102+
return def
103+
}
104+
}

cmd/api/models.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import "github.com/djthorpe/go-tablewriter"
4+
5+
type ModelsCmd struct{}
6+
7+
func (cmd *ModelsCmd) Run(ctx *Globals) error {
8+
if models, err := ctx.client.ListModels(ctx.ctx); err != nil {
9+
return err
10+
} else {
11+
return ctx.writer.Write(models, tablewriter.OptHeader())
12+
}
13+
}

cmd/api/ping.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package main
2+
3+
type PingCmd struct{}
4+
5+
func (cmd *PingCmd) Run(ctx *Globals) error {
6+
if err := ctx.client.Ping(ctx.ctx); err != nil {
7+
return err
8+
}
9+
return ctx.writer.Writeln("OK")
10+
}

cmd/cli/delete.go

Lines changed: 0 additions & 13 deletions
This file was deleted.

cmd/cli/download.go

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)