Skip to content

Commit e61bc83

Browse files
authored
Merge pull request #55 from mutablelogic/stream
Stream
2 parents 05c6af4 + e9fbdb6 commit e61bc83

File tree

16 files changed

+324
-34
lines changed

16 files changed

+324
-34
lines changed

Makefile

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,17 @@ ifeq ($(GGML_CUDA),1)
3030
endif
3131

3232
# Targets
33-
all: server cli
33+
all: whisper
3434

3535
# Generate the pkg-config files
3636
generate: mkdir go-tidy
3737
@echo "Generating pkg-config"
3838
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} go generate ./sys/whisper
3939

40-
# Make server
41-
server: mkdir generate go-tidy libwhisper libggml
42-
@echo "Building whisper-server"
43-
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} build ${BUILD_FLAGS} -o ${BUILD_DIR}/whisper-server ./cmd/server
44-
45-
# Make cli
46-
cli: mkdir generate go-tidy
47-
@echo "Building whisper-cli"
48-
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} build ${BUILD_FLAGS} -o ${BUILD_DIR}/whisper-cli ./cmd/cli
40+
# Make whisper
41+
whisper: mkdir generate go-tidy libwhisper libggml
42+
@echo "Building whisper"
43+
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} build ${BUILD_FLAGS} -o ${BUILD_DIR}/whisper ./cmd/whisper
4944

5045
# Build docker container
5146
docker: docker-dep submodule
@@ -75,11 +70,6 @@ libggml: submodule
7570
@echo "Building libggml.a"
7671
@cd third_party/whisper.cpp && make -j$(nproc) libggml.a
7772

78-
# Build whisper-server
79-
whisper-server: submodule
80-
@echo "Building whisper-server"
81-
@cd third_party/whisper.cpp && make -j$(nproc) server
82-
8373
# Push docker container
8474
docker-push: docker-dep
8575
@echo push docker image: ${BUILD_TAG}

cmd/server/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
// Packages
1414
context "github.com/mutablelogic/go-server/pkg/context"
1515
httpserver "github.com/mutablelogic/go-server/pkg/httpserver"
16-
whisper "github.com/mutablelogic/go-whisper/pkg/whisper"
16+
whisper "github.com/mutablelogic/go-whisper"
1717
api "github.com/mutablelogic/go-whisper/pkg/whisper/api"
1818
version "github.com/mutablelogic/go-whisper/pkg/whisper/version"
1919
)

cmd/whisper/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+
"log"
5+
6+
// Packages
7+
"github.com/djthorpe/go-tablewriter"
8+
)
9+
10+
type DownloadCmd struct {
11+
Model string `arg:"" help:"Model to download"`
12+
}
13+
14+
func (cmd *DownloadCmd) Run(ctx *Globals) error {
15+
model, err := ctx.service.DownloadModel(ctx.ctx, cmd.Model, func(curBytes, totalBytes uint64) {
16+
log.Printf("Downloaded %d of %d bytes", curBytes, totalBytes)
17+
})
18+
if err != nil {
19+
return err
20+
}
21+
return ctx.writer.Write(model, tablewriter.OptHeader())
22+
}

cmd/whisper/main.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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+
ctx "github.com/mutablelogic/go-server/pkg/context"
13+
whisper "github.com/mutablelogic/go-whisper"
14+
)
15+
16+
type Globals struct {
17+
NoGPU bool `name:"nogpu" help:"Disable GPU acceleration"`
18+
Debug bool `name:"debug" help:"Enable debug output"`
19+
Dir string `name:"dir" help:"Path to model store, uses ${WHISPER_DIR} " default:"${WHISPER_DIR}"`
20+
21+
// Writer, service and context
22+
writer *tablewriter.Writer
23+
service *whisper.Whisper
24+
ctx context.Context
25+
}
26+
27+
type CLI struct {
28+
Globals
29+
Models ModelsCmd `cmd:"models" help:"List models"`
30+
Download DownloadCmd `cmd:"download" help:"Download a model"`
31+
Server ServerCmd `cmd:"models" help:"Run the whisper server"`
32+
}
33+
34+
func main() {
35+
// The name of the executable
36+
name, err := os.Executable()
37+
if err != nil {
38+
panic(err)
39+
} else {
40+
name = filepath.Base(name)
41+
}
42+
43+
// Create a cli parser
44+
cli := CLI{}
45+
cmd := kong.Parse(&cli,
46+
kong.Name(name),
47+
kong.Description("speech transcription and translation service"),
48+
kong.UsageOnError(),
49+
kong.ConfigureHelp(kong.HelpOptions{Compact: true}),
50+
kong.Vars{
51+
"WHISPER_DIR": dirEnvOrDefault(name),
52+
},
53+
)
54+
55+
// Create a whisper server - set options
56+
opts := []whisper.Opt{}
57+
if cli.Globals.Debug {
58+
opts = append(opts, whisper.OptDebug())
59+
}
60+
if cli.Globals.NoGPU {
61+
opts = append(opts, whisper.OptNoGPU())
62+
}
63+
64+
// Create directory if it doesn't exist
65+
if err := os.MkdirAll(cli.Globals.Dir, 0755); err != nil {
66+
cmd.FatalIfErrorf(err)
67+
return
68+
}
69+
70+
// Create a whisper server - create
71+
service, err := whisper.New(cli.Globals.Dir, opts...)
72+
if err != nil {
73+
cmd.FatalIfErrorf(err)
74+
return
75+
} else {
76+
cli.Globals.service = service
77+
}
78+
defer service.Close()
79+
80+
// Create a tablewriter object with text output
81+
writer := tablewriter.New(os.Stdout, tablewriter.OptOutputText())
82+
cli.Globals.writer = writer
83+
84+
// Create a context
85+
cli.Globals.ctx = ctx.ContextForSignal(os.Interrupt, syscall.SIGQUIT)
86+
87+
// Run the command
88+
if err := cmd.Run(&cli.Globals); err != nil {
89+
cmd.FatalIfErrorf(err)
90+
}
91+
}
92+
93+
func dirEnvOrDefault(name string) string {
94+
if dir := os.Getenv("WHISPER_DIR"); dir != "" {
95+
return dir
96+
}
97+
if dir, err := os.UserCacheDir(); err == nil {
98+
return filepath.Join(dir, name)
99+
}
100+
return os.TempDir()
101+
}

cmd/whisper/models.go

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

cmd/whisper/server.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
7+
// Packages
8+
"github.com/mutablelogic/go-server/pkg/httpserver"
9+
"github.com/mutablelogic/go-whisper/pkg/whisper/api"
10+
)
11+
12+
type ServerCmd struct {
13+
Endpoint string `name:"endpoint" help:"Endpoint for the server" default:"/api/v1"`
14+
Listen string `name:"listen" help:"Listen address for the server" default:"localhost:8080"`
15+
}
16+
17+
func (cmd *ServerCmd) Run(ctx *Globals) error {
18+
// Create a mux for serving requests, then register the endpoints with the mux
19+
mux := http.NewServeMux()
20+
21+
// Register the endpoints
22+
api.RegisterEndpoints(cmd.Endpoint, mux, ctx.service)
23+
24+
// Create a new HTTP server
25+
log.Println("List address", cmd.Listen)
26+
server, err := httpserver.Config{
27+
Listen: cmd.Listen,
28+
Router: mux,
29+
}.New()
30+
if err != nil {
31+
return err
32+
}
33+
34+
// Run the server until CTRL+C
35+
log.Println("Press CTRL+C to exit")
36+
return server.Run(ctx.ctx)
37+
}

etc/Dockerfile.linux-amd64

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ RUN make -j$(nproc) server
3232
FROM ${BASE_CUDA_RUN_CONTAINER} AS runtime
3333
ARG CUDA_MAIN_VERSION=12.5
3434
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install libgomp1
35-
COPY --from=build /app/build/whisper-server /usr/local/bin/whisper-server
35+
COPY --from=build /app/build/whisper /usr/local/bin/whisper
3636
ENV LD_LIBRARY_PATH=/usr/local/cuda-${CUDA_MAIN_VERSION}/compat:$LD_LIBRARY_PATH
3737

3838
# Expose
39-
ENTRYPOINT [ "/usr/local/bin/whisper-server" ]
39+
ENTRYPOINT [ "/usr/local/bin/whisper" ]
40+
CMD [ "server", "--dir=/data" ]

etc/Dockerfile.linux-arm64

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ RUN make -j$(nproc) server
3232
FROM ${BASE_CUDA_RUN_CONTAINER} AS runtime
3333
ARG CUDA_MAIN_VERSION=12.2
3434
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install libgomp1
35-
COPY --from=build /app/build/whisper-server /usr/local/bin/whisper-server
35+
COPY --from=build /app/build/whisper /usr/local/bin/whisper
3636
ENV LD_LIBRARY_PATH=/usr/local/cuda-${CUDA_MAIN_VERSION}/compat:$LD_LIBRARY_PATH
3737

3838
# Expose
39-
ENTRYPOINT [ "/usr/local/bin/whisper-server" ]
39+
ENTRYPOINT [ "/usr/local/bin/whisper" ]
40+
CMD [ "server", "--dir=/data" ]
File renamed without changes.

pkg/whisper/api/logging.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package api
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"sync/atomic"
7+
"time"
8+
)
9+
10+
var (
11+
req int32
12+
)
13+
14+
func wrapLogging(fn http.HandlerFunc) http.HandlerFunc {
15+
return func(w http.ResponseWriter, r *http.Request) {
16+
req := nextReq()
17+
delta := time.Now()
18+
log.Printf("R%d %s %s", req, r.Method, r.URL)
19+
fn(w, r)
20+
log.Printf("R%d Took %v", req, time.Since(delta).Truncate(time.Millisecond))
21+
}
22+
}
23+
24+
func nextReq() int32 {
25+
return atomic.AddInt32(&req, 1)
26+
}

0 commit comments

Comments
 (0)