Skip to content

Commit aa4f71d

Browse files
Merge pull request #3 from FootprintAI/fix---update-flags
fix: fix flags used in llama.cpp and whisper.cpp
2 parents b4e5ebc + 827824b commit aa4f71d

3 files changed

Lines changed: 108 additions & 43 deletions

File tree

README.md

Lines changed: 104 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,39 @@
22

33
Go bindings for C++ inference frameworks via CGO, with prebuilt static libraries for zero-dependency builds.
44

5+
## Why go-nativeml?
6+
7+
| Approach | Build complexity | Runtime dependency | `go mod vendor` | GPU support |
8+
|----------|------------------|--------------------|-----------------|-------------|
9+
| **go-nativeml (this project)** | `go build -tags llamacpp` — just works | None — static linking | Works via `go:embed` | Metal, CPU |
10+
| HTTP/subprocess wrapper (e.g. ollama server) | Separate process to manage | Running server required | N/A | Depends on server |
11+
| Dynamic linking (shared `.so`/`.dylib`) | Must install libs on every machine | Shared libs must exist at runtime | Cannot vendor native libs | Depends on build |
12+
| Build from source at `go get` | Requires C++ toolchain + cmake on every machine | None | Fragile — source download at build | Depends on build |
13+
| Pure Go reimplementation | Simple | None | Works | Limited/none |
14+
15+
**Key advantages:**
16+
17+
- **Zero build-time setup** — prebuilt `.a` files ship with the Go module. No cmake, no C++ toolchain, no downloads.
18+
- **Vendoring works**`embed.go` files use `//go:embed` to ensure `go mod vendor` captures headers and static libraries. Standard Go tooling just works.
19+
- **No runtime dependencies** — everything is statically linked. No shared libraries to install, no server to run.
20+
- **Stub fallback** — without build tags, all packages compile to stubs returning errors. CI, linters, and `go build ./...` work everywhere without CGO.
21+
- **Type-safe Go API** — idiomatic option pattern, proper error handling, streaming callbacks. No shell-outs or HTTP round-trips.
22+
523
## Supported Frameworks
624

725
| Framework | Version | Package | Build Tag | Capabilities | Status |
826
|-----------|---------|---------|-----------|--------------|--------|
927
| [llama.cpp](https://github.com/ggerganov/llama.cpp) | `b8220` | `ggml/llamacpp` | `llamacpp` | Text generation, embeddings, tokenization | Available |
10-
| [whisper.cpp](https://github.com/ggerganov/whisper.cpp) | `v1.8.3` | `ggml/whispercpp` | `whispercpp` | Speech-to-text | Planned |
28+
| [whisper.cpp](https://github.com/ggerganov/whisper.cpp) | `v1.8.3` | `ggml/whispercpp` | `whispercpp` | Speech-to-text transcription | Available |
1129

1230
## Quick Start
1331

1432
```bash
1533
go get github.com/footprintai/go-nativeml
1634
```
1735

36+
### llama.cpp — Text Generation
37+
1838
```go
1939
import "github.com/footprintai/go-nativeml/ggml/llamacpp"
2040

@@ -34,55 +54,69 @@ ctx.GenerateStream("Hello, world", func(token string) bool {
3454
}, llamacpp.WithMaxTokens(256), llamacpp.WithTemperature(0.8))
3555
```
3656

57+
### whisper.cpp — Speech-to-Text
58+
59+
```go
60+
import "github.com/footprintai/go-nativeml/ggml/whispercpp"
61+
62+
model, _ := whispercpp.LoadModel("ggml-base.bin", whispercpp.WithGPU(true))
63+
defer model.Close()
64+
65+
// pcmData: 16kHz mono float32 samples
66+
segments, _ := model.Transcribe(pcmData,
67+
whispercpp.WithLanguage("en"),
68+
whispercpp.WithThreads(4),
69+
)
70+
for _, seg := range segments {
71+
fmt.Printf("[%s -> %s] %s\n", seg.Start, seg.End, seg.Text)
72+
}
73+
```
74+
3775
## Build Tags
3876

3977
| Tag | Behavior |
4078
|-----|----------|
4179
| _(none)_ | Stub implementations that return errors. Allows `go build` without CGO. |
4280
| `llamacpp` | Enables CGO bindings to prebuilt llama.cpp static libraries. |
81+
| `whispercpp` | Enables CGO bindings to prebuilt whisper.cpp static libraries. |
4382

4483
```bash
4584
# Stub build (no CGO required)
4685
go build ./...
4786

4887
# CGO build with llama.cpp
4988
CGO_ENABLED=1 go build -tags llamacpp ./...
89+
90+
# CGO build with whisper.cpp
91+
CGO_ENABLED=1 go build -tags whispercpp ./...
92+
93+
# Both
94+
CGO_ENABLED=1 go build -tags "llamacpp whispercpp" ./...
5095
```
5196

5297
## API
5398

54-
### Lifecycle
99+
### llamacpp
55100

56101
```go
57-
llamacpp.Init() // initialize backend
58-
llamacpp.Shutdown() // cleanup
59-
```
60-
61-
### Model
102+
// Lifecycle
103+
llamacpp.Init()
104+
llamacpp.Shutdown()
62105

63-
```go
64-
model, err := llamacpp.LoadModel(path,
65-
llamacpp.WithGPULayers(n), // layers to offload to GPU
66-
)
106+
// Model
107+
model, err := llamacpp.LoadModel(path, llamacpp.WithGPULayers(n))
67108
model.Close()
68-
model.EmbeddingSize() // returns embedding dimension
69-
```
70-
71-
### Context
109+
model.EmbeddingSize()
72110

73-
```go
111+
// Context
74112
ctx, err := model.NewContext(
75113
llamacpp.WithContextSize(2048),
76114
llamacpp.WithThreads(4),
77-
llamacpp.WithEmbeddings(), // enable embedding mode
115+
llamacpp.WithEmbeddings(),
78116
)
79117
ctx.Close()
80-
```
81118

82-
### Generation
83-
84-
```go
85-
// Blocking
119+
// Generation (blocking)
86120
text, err := ctx.Generate(prompt,
87121
llamacpp.WithMaxTokens(256),
88122
llamacpp.WithTemperature(0.8),
@@ -93,24 +127,45 @@ text, err := ctx.Generate(prompt,
93127
llamacpp.WithSeed(42),
94128
)
95129

96-
// Streaming
130+
// Generation (streaming)
97131
err := ctx.GenerateStream(prompt, func(token string) bool {
98132
fmt.Print(token)
99133
return true // return false to cancel
100134
}, llamacpp.WithMaxTokens(256))
101-
```
102135

103-
### Embeddings
136+
// Embeddings
137+
embeddings, err := ctx.GetEmbeddings("some text") // []float32
104138

105-
```go
106-
ctx, _ := model.NewContext(llamacpp.WithContextSize(512), llamacpp.WithEmbeddings())
107-
embeddings, err := ctx.GetEmbeddings("some text") // []float32
139+
// Tokenization
140+
tokens, err := ctx.Tokenize("some text") // []int
108141
```
109142

110-
### Tokenization
143+
### whispercpp
111144

112145
```go
113-
tokens, err := ctx.Tokenize("some text") // []int
146+
// Model
147+
model, err := whispercpp.LoadModel(path,
148+
whispercpp.WithGPU(true),
149+
whispercpp.WithFlashAttention(true),
150+
)
151+
model.Close()
152+
model.IsMultilingual()
153+
154+
// Transcription (pcmData: 16kHz mono float32)
155+
segments, err := model.Transcribe(pcmData,
156+
whispercpp.WithThreads(4),
157+
whispercpp.WithLanguage("en"),
158+
whispercpp.WithTranslate(false),
159+
whispercpp.WithTimestamps(true),
160+
whispercpp.WithTokenTimestamps(false),
161+
whispercpp.WithSingleSegment(false),
162+
whispercpp.WithTemperature(0.0),
163+
whispercpp.WithMaxTokens(0),
164+
whispercpp.WithPrompt(""),
165+
)
166+
167+
// Utilities
168+
id := whispercpp.LangID("en") // language string -> ID
114169
```
115170

116171
## Examples
@@ -151,21 +206,29 @@ make clean # Remove temp build dirs
151206

152207
## Adding New Platforms
153208

154-
1. Build llama.cpp static libraries for the target platform
155-
2. Place `.a` files in `third_party/llama.cpp/prebuilt/<os>-<arch>/`
156-
3. Add a `#cgo <os>,<arch> LDFLAGS` directive in `ggml/llamacpp/llamacpp.go`
209+
1. Build static libraries for the target platform
210+
2. Place `.a` files in `ggml/<pkg>/third_party/prebuilt/<os>-<arch>/`
211+
3. Add a `#cgo <os>,<arch> LDFLAGS` directive in the corresponding `.go` file
157212

158213
## Project Structure
159214

160215
```
161-
ggml/llamacpp/ Go bindings for llama.cpp
162-
llamacpp.go CGO implementation (build tag: llamacpp)
163-
llamacpp_stub.go Stub implementation (default)
164-
options.go Option builders for model, context, generation
165-
wrapper.h/.cpp C++ bridge to llama.cpp APIs
166-
bridge.c CGO callback adapter
167-
third_party/llama.cpp/ Upstream headers + prebuilt static libraries
168-
examples/ Usage examples (generate, embeddings)
216+
ggml/
217+
llamacpp/ Go bindings for llama.cpp
218+
llamacpp.go CGO implementation (build tag: llamacpp)
219+
llamacpp_stub.go Stub implementation (default)
220+
options.go Option builders
221+
wrapper.h/.cpp C++ bridge to llama.cpp APIs
222+
bridge.c CGO callback adapter
223+
embed.go go:embed for vendoring support
224+
third_party/ Upstream headers + prebuilt .a files
225+
whispercpp/ Go bindings for whisper.cpp
226+
whispercpp.go CGO implementation (build tag: whispercpp)
227+
whispercpp_stub.go Stub implementation (default)
228+
options.go Option builders
229+
embed.go go:embed for vendoring support
230+
third_party/ Upstream headers + prebuilt .a files
231+
examples/ Usage examples (generate, embeddings)
169232
```
170233

171234
## License

ggml/llamacpp/llamacpp.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ package llamacpp
1414
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/third_party/prebuilt/darwin-amd64
1515
#cgo linux,amd64 LDFLAGS: -L${SRCDIR}/third_party/prebuilt/linux-amd64
1616
#cgo LDFLAGS: -lcommon -lllama -lggml-cpu -lggml-base -lggml -lstdc++ -lm
17-
#cgo darwin LDFLAGS: -framework Accelerate -framework Metal -framework Foundation
17+
#cgo darwin LDFLAGS: -lggml-blas -lggml-metal -L/usr/local/opt/libomp/lib -L/opt/homebrew/opt/libomp/lib -lomp -framework Accelerate -framework Metal -framework Foundation
18+
#cgo linux LDFLAGS: -lpthread -ldl -lrt -lgomp
1819
#include <stdlib.h>
1920
#include <stdbool.h>
2021
#include "wrapper.h"

ggml/whispercpp/whispercpp.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ package whispercpp
1414
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/third_party/prebuilt/darwin-amd64
1515
#cgo linux,amd64 LDFLAGS: -L${SRCDIR}/third_party/prebuilt/linux-amd64
1616
#cgo LDFLAGS: -lwhisper -lcommon -lggml-cpu -lggml-base -lggml -lstdc++ -lm
17-
#cgo darwin LDFLAGS: -framework Accelerate -framework Metal -framework Foundation
17+
#cgo darwin LDFLAGS: -lggml-blas -lggml-metal -L/usr/local/opt/libomp/lib -L/opt/homebrew/opt/libomp/lib -lomp -framework Accelerate -framework Metal -framework Foundation
18+
#cgo linux LDFLAGS: -lpthread -ldl -lrt -lgomp
1819
#include <stdlib.h>
1920
#include "whisper.h"
2021
*/

0 commit comments

Comments
 (0)