Is the Go binding still being maintained?
Hi there,
Is the Go binding for whisper.cpp still being maintained?
Currently, the documentation for the Go binding contains many errors. Following the documentation, it’s even impossible to compile the basic libwhisper.a. It seems that the core code of whisper.cpp has undergone significant changes, but the Go binding hasn’t been updated accordingly.
I sincerely hope the authors or contributors could update the Go binding. If there’s anything I can help with, please feel free to let me know.
Personally, I believe that, besides C++, Golang is one of the most suitable programming languages for tasks like this. I really hope the Go binding will continue to be maintained and improved.
Thank you very much!
When migrating to CMake ~241214 , the libwhisper.a target was not included in the migration https://github.com/ggerganov/whisper.cpp/issues/2696#issuecomment-2571536917
The Go code isn’t written by someone used to Go trying to avoid allocations. Working bindings are really helpful to test things
I managed to build whisper v1.7.4, link it and run it with this:
cmake ./whisper.cpp -B ./whisper.cpp/build
cmake --build ./whisper.cpp/build --config Release
WHISPER_DIR=$(abspath ../whisper.cpp)
INCLUDE_PATH=$(WHISPER_DIR)/include:$(WHISPER_DIR)/ggml/include
LIBRARY_PATH=$(WHISPER_DIR)/build/src/
C_INCLUDE_PATH="${INCLUDE_PATH}" LIBRARY_PATH="${LIBRARY_PATH}" LD_LIBRARY_PATH="${LIBRARY_PATH}" go run main.go
On macOS 15.2 M that did not work:
W='/opt/oth/whisper.cpp' C_INCLUDE_PATH="$W/include:$W/ggml/include" LIBRARY_PATH="$W/build/src" LD_LIBRARY_PATH="$LIBRARY_PATH" go run ./myGoMainDir
/opt/homebrew/Cellar/go/1.23.4/libexec/pkg/tool/darwin_arm64/link: running cc failed: exit status 1 /usr/bin/cc -arch arm64 -Wl,-S -Wl,-x -o $WORK/b001/exe/gp-gisper /var/folders/sq/0x1_9fyn1bv907s7y pfryt1c0000gn/T/go-link-1513937620/go.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-15 13937620/000000.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000001.o /var /folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000002.o /var/folders/sq/0x1_9fyn1b v907s7ypfryt1c0000gn/T/go-link-1513937620/000003.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T /go-link-1513937620/000004.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/00 0005.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000006.o /var/folders/sq /0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000007.o /var/folders/sq/0x1_9fyn1bv907s7ypfry t1c0000gn/T/go-link-1513937620/000008.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000009.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000010.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000011.o /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-link-1513937620/000012.o -lresolv -O2 -g -lwhisper -lm -lstdc++ -fopenmp -framework Accelerate -framework Metal -framework Foundation -framework CoreGraphics -O2 -g -framework CoreFoundation -framework CoreFoundation -framework Security clang: error: unsupported option '-fopenmp'
to get OpenMP on macOS:
brew install llwm
export CC="$(brew --prefix)/opt/llvm/bin/clang"
export CXX="$(brew --prefix)/opt/llvm/bin/clang++"
export PATH="$(brew --prefix)/opt/llvm/bin:$PATH"
result: dyld[99921]: Library not loaded: @rpath/libwhisper.1.dylib Referenced from: <948A0163-1AA2-328E-DBAB-8AD0E58E056B> /private/var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-build3222785088/b001/exe/gp-gisper Reason: no LC_RPATH's found signal: abort trap
find /opt/oth/whisper.cpp -name libwhisper.1.dylib /opt/oth/whisper.cpp/build/src/libwhisper.1.dylib
Go bindings macOS 15.2 M 250109 hash 2ab2eb51
whisper.cpp with Core ML and OpenMP
// // get non-apple llvm that supports OpenMP — as brew brew install llvm // — as user in whisper.cpp directory: export OpenMP_ROOT=$(brew --prefix)/opt/libomp cmake -B build -DWHISPER_COREML=1 -- Found OpenMP: TRUE (found version "5.1") -- CoreML framework found cmake --build build -j --config Release
run Go code using whisper.cpp as library
// use model large-v3-turbo // use Core ML export CC="$(brew --prefix)/opt/llvm/bin/clang" export DYLD_LIBRARY_PATH=/opt/oth/whisper.cpp/build/src W='/opt/oth/whisper.cpp' C_INCLUDE_PATH="$W/include:$W/ggml/include" LIBRARY_PATH="$W/build/src" LD_LIBRARY_PATH="$LIBRARY_PATH" go run ./GoMainDirectory
whisper_init_state: loading Core ML model from '/opt/oth/whisper.cpp/models/ggml-large-v3-turbo-encoder.mlmodelc' whisper_init_state: Core ML model loaded And so, my fellow Americans…
The documentation's sample code doesn't seem to even use the methods provided by the Context object. It has context.Process(samples, nil, nil in the sample code, but that method doesn't exist in the Context object's manifest below it.
The Go package documentation outlines what is possible: https://pkg.go.dev/github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper#Context
Looking at this naive Go code, you can implement whatever you need: https://github.com/ggerganov/whisper.cpp/blob/master/bindings/go/examples/go-whisper/main.go — in main(), Process is a top-level function of the main package eventually delegating to context.Process: https://github.com/ggerganov/whisper.cpp/blob/7a423f1c008c1d7efdee91e1ce2f8ae22f42f43b/bindings/go/examples/go-whisper/process.go#L70
sample-code invokes NewContext here: https://github.com/ggerganov/whisper.cpp/blob/7a423f1c008c1d7efdee91e1ce2f8ae22f42f43b/bindings/go/examples/go-whisper/process.go#L18
For some reason, Context configuration is with flag parsing: https://github.com/ggerganov/whisper.cpp/blob/7a423f1c008c1d7efdee91e1ce2f8ae22f42f43b/bindings/go/examples/go-whisper/flags.go#L91
The download URL in the go binding sample main.go was wrong. I submitted a Pull Request with the updated URL: #2756
Set LLVM and OpenMP environment variables
export PATH="/usr/local/opt/llvm/bin:$PATH" export LDFLAGS="-L/usr/local/opt/llvm/lib -L/usr/local/opt/libomp/lib" export CPPFLAGS="-I/usr/local/opt/llvm/include -I/usr/local/opt/libomp/include -Xpreprocessor -fopenmp" export CFLAGS="-I/usr/local/opt/libomp/include" export CXXFLAGS="-I/usr/local/opt/libomp/include"
Ensure Homebrew-installed clang is used instead of the system default
export CC="/usr/local/opt/llvm/bin/clang" export CXX="/usr/local/opt/llvm/bin/clang++"
Since macOS's default Xcode does not support OpenMP, the script specifies the compiler tools.
Another approach is to modify the source code in whisper.cpp by removing:
//#cgo LDFLAGS: -lwhisper -lggml -lggml-base -lggml-cpu -lm -lstdc++ -fopenmp #cgo LDFLAGS: -lwhisper -lggml -lggml-base -lggml-cpu -lm -lstdc++
-- --main.go --whisper.cpp
MacOS
brew install llvm
cd whisper.cpp
cmake -B build
cmake --build build --config Release
cd ../
> demo.sh
export CC="$(brew --prefix)/opt/llvm/bin/clang"
export CXX="$(brew --prefix)/opt/llvm/bin/clang++"
ROOT="$(pwd)/whisper.cpp"
export CGO_ENABLED=1
export DYLD_LIBRARY_PATH="${ROOT}/build/src:$DYLD_LIBRARY_PATH"
export C_INCLUDE_PATH="${ROOT}/include:${ROOT}/ggml/include"
export LIBRARY_PATH="${ROOT}/build/src:${ROOT}/build/ggml/src"
export LD_LIBRARY_PATH="$LIBRARY_PATH"
export CGO_LDFLAGS="-L${ROOT}/build/src -lwhisper -Wl,-rpath,${ROOT}/build/src -Wl,-rpath,${ROOT}/build/ggml/src"
go run main.go
Windows
cd whisper.cpp
cmake -B build
cmake --build build --config Release
cd ../
> demo..bat
set ROOT=%CD%
set CGO_ENABLED=1
set CGO_CFLAGS=-I%ROOT%/whisper.cpp/include -I%ROOT%/whisper.cpp/ggml/include
set CGO_LDFLAGS=-L%ROOT%/whisper.cpp/build/src/Release -lwhisper -L%ROOT%/whisper.cpp/build/ggml/src/Release -lggml
go run main.go