Skip to content

Commit 171f62a

Browse files
KitaitiMakotoliuyang.marshall
authored andcommitted
ruby : extend API (ggml-org#2551)
* Handle objs in Ruby code * Add task to make Makefile * Share commont constance in test suites * Add model-related APIs * Add Whisper::Model class * Add tests for Whisper::Model * Add missing LDFLAG -lstdc++ * Add tests for Whisper.log_set * Add Whisper.set_log * Define log level * Add document on logging * Add license section to README * Add document on Whisper::Model * Fix examples in README * Add test for Model with GC * Make dependency on Makefile more accurate * Fix bug about Whisper::Model and GC
1 parent e307197 commit 171f62a

File tree

10 files changed

+564
-93
lines changed

10 files changed

+564
-93
lines changed

bindings/ruby/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,63 @@ whisper.transcribe("path/to/audio.wav", params)
107107

108108
```
109109

110+
You can see model information:
111+
112+
```ruby
113+
whisper = Whisper::Context.new("path/to/model.bin")
114+
model = whisper.model
115+
116+
model.n_vocab # => 51864
117+
model.n_audio_ctx # => 1500
118+
model.n_audio_state # => 512
119+
model.n_audio_head # => 8
120+
model.n_audio_layer # => 6
121+
model.n_text_ctx # => 448
122+
model.n_text_state # => 512
123+
model.n_text_head # => 8
124+
model.n_text_layer # => 6
125+
model.n_mels # => 80
126+
model.ftype # => 1
127+
model.type # => "base"
128+
129+
```
130+
131+
You can set log callback:
132+
133+
```ruby
134+
prefix = "[MyApp] "
135+
log_callback = ->(level, buffer, user_data) {
136+
case level
137+
when Whisper::LOG_LEVEL_NONE
138+
puts "#{user_data}none: #{buffer}"
139+
when Whisper::LOG_LEVEL_INFO
140+
puts "#{user_data}info: #{buffer}"
141+
when Whisper::LOG_LEVEL_WARN
142+
puts "#{user_data}warn: #{buffer}"
143+
when Whisper::LOG_LEVEL_ERROR
144+
puts "#{user_data}error: #{buffer}"
145+
when Whisper::LOG_LEVEL_DEBUG
146+
puts "#{user_data}debug: #{buffer}"
147+
when Whisper::LOG_LEVEL_CONT
148+
puts "#{user_data}same to previous: #{buffer}"
149+
end
150+
}
151+
Whisper.log_set log_callback, prefix
152+
```
153+
154+
Using this feature, you are also able to suppress log:
155+
156+
```ruby
157+
Whisper.log_set ->(level, buffer, user_data) {
158+
# do nothing
159+
}, nil
160+
Whisper::Context.new(MODEL)
161+
```
162+
163+
License
164+
-------
165+
166+
The same to [whisper.cpp][].
167+
110168
[whisper.cpp]: https://github.com/ggerganov/whisper.cpp
111169
[models]: https://github.com/ggerganov/whisper.cpp/tree/master/models

bindings/ruby/Rakefile

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,39 @@ CLEAN.include FileList[
2323
"ext/depend"
2424
]
2525

26-
task build: SOURCES + FileList[
27-
"ext/extconf.rb",
28-
"ext/ruby_whisper.h",
29-
"ext/ruby_whisper.cpp",
30-
"whispercpp.gemspec",
31-
]
26+
task build: FileList[
27+
"ext/Makefile",
28+
"ext/ruby_whisper.h",
29+
"ext/ruby_whisper.cpp",
30+
"whispercpp.gemspec",
31+
]
3232

3333
directory "pkg"
3434
CLOBBER.include "pkg"
3535

3636
TEST_MODEL = "../../models/ggml-base.en.bin"
3737
LIB_NAME = "whisper".ext(RbConfig::CONFIG["DLEXT"])
38+
SO_FILE = File.join("ext", LIB_NAME)
3839
LIB_FILE = File.join("lib", LIB_NAME)
3940

40-
directory "lib"
41-
task LIB_FILE => SOURCES + ["lib"] do |t|
41+
file "ext/Makefile" => ["ext/extconf.rb", "ext/ruby_whisper.h", "ext/ruby_whisper.cpp"] + SOURCES do |t|
42+
Dir.chdir "ext" do
43+
ruby "extconf.rb"
44+
end
45+
end
46+
47+
file SO_FILE => "ext/Makefile" do |t|
4248
Dir.chdir "ext" do
43-
sh "ruby extconf.rb"
4449
sh "make"
4550
end
46-
mv "ext/#{LIB_NAME}", t.name
4751
end
4852
CLEAN.include LIB_FILE
4953

54+
directory "lib"
55+
file LIB_FILE => [SO_FILE, "lib"] do |t|
56+
copy t.source, t.name
57+
end
58+
5059
Rake::TestTask.new do |t|
5160
t.test_files = FileList["tests/test_*.rb"]
5261
end

bindings/ruby/ext/extconf.rb

Lines changed: 21 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
# need to use c++ compiler flags
44
$CXXFLAGS << ' -std=c++11'
5+
6+
$LDFLAGS << ' -lstdc++'
7+
58
# Set to true when building binary gems
69
if enable_config('static-stdlib', false)
710
$LDFLAGS << ' -static-libgcc -static-libstdc++'
@@ -12,34 +15,6 @@
1215
$CXXFLAGS << ' -march=native -mtune=native'
1316
end
1417

15-
def with_disabling_unsupported_files
16-
disabled_files = []
17-
18-
unless $GGML_METAL
19-
disabled_files << 'ggml-metal.h' << 'ggml-metal.m'
20-
end
21-
22-
unless $GGML_METAL_EMBED_LIBRARY
23-
disabled_files << 'ggml-metal.metal'
24-
end
25-
26-
unless $OBJ_ALL&.include? 'ggml-blas.o'
27-
disabled_files << 'ggml-blas.h' << 'ggml-blas.cpp'
28-
end
29-
30-
disabled_files.filter! {|file| File.exist? file}
31-
32-
disabled_files.each do |file|
33-
File.rename file, "#{file}.disabled"
34-
end
35-
36-
yield
37-
38-
disabled_files.each do |file|
39-
File.rename "#{file}.disabled", file
40-
end
41-
end
42-
4318
if ENV['WHISPER_METAL']
4419
$GGML_METAL ||= true
4520
$DEPRECATE_WARNING ||= true
@@ -66,10 +41,10 @@ def with_disabling_unsupported_files
6641
$MK_NVCCFLAGS = '-std=c++11'
6742
$MK_LDFLAGS = ''
6843

69-
$OBJ_GGML = ''
70-
$OBJ_WHISPER = ''
71-
$OBJ_COMMON = ''
72-
$OBJ_SDL = ''
44+
$OBJ_GGML = []
45+
$OBJ_WHISPER = []
46+
$OBJ_COMMON = []
47+
$OBJ_SDL = []
7348

7449
$MK_CPPFLAGS << ' -D_XOPEN_SOURCE=600'
7550

@@ -152,50 +127,51 @@ def with_disabling_unsupported_files
152127
$MK_CPPFLAGS << ' -DACCELERATE_NEW_LAPACK'
153128
$MK_CPPFLAGS << ' -DACCELERATE_LAPACK_ILP64'
154129
$MK_LDFLAGS << ' -framework Accelerate'
155-
$OBJ_GGML << ' ggml-blas.o'
130+
$OBJ_GGML << 'ggml-blas.o'
156131
end
157132
end
158133

159134
if ENV['GGML_OPENBLAS']
160135
$MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas`.chomp}"
161136
$MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas)`.chomp}"
162137
$MK_LDFLAGS << " #{`pkg-config --libs openblas`}"
163-
$OBJ_GGML << ' ggml-blas.o'
138+
$OBJ_GGML << 'ggml-blas.o'
164139
end
165140

166141
if ENV['GGML_OPENBLAS64']
167142
$MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas64`.chomp}"
168143
$MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas64)`.chomp}"
169144
$MK_LDFLAGS << " #{`pkg-config --libs openblas64`}"
170-
$OBJ_GGML << ' ggml-blas.o'
145+
$OBJ_GGML << 'ggml-blas.o'
171146
end
172147

173148
if $GGML_METAL
174149
$MK_CPPFLAGS << ' -DGGML_USE_METAL'
175150
$MK_LDFLAGS << ' -framework Foundation -framework Metal -framework MetalKit'
176-
$OBJ_GGML << ' ggml-metal.o'
151+
$OBJ_GGML << 'ggml-metal.o'
177152

178153
if ENV['GGML_METAL_NDEBUG']
179154
$MK_CPPFLAGS << ' -DGGML_METAL_NDEBUG'
180155
end
181156

182157
if $GGML_METAL_EMBED_LIBRARY
183158
$MK_CPPFLAGS << ' -DGGML_METAL_EMBED_LIBRARY'
184-
$OBJ_GGML << ' ggml-metal-embed.o'
159+
$OBJ_GGML << 'ggml-metal-embed.o'
185160
end
186161
end
187162

188163
$OBJ_GGML <<
189-
' ggml.o' <<
190-
' ggml-alloc.o' <<
191-
' ggml-backend.o' <<
192-
' ggml-quants.o' <<
193-
' ggml-aarch64.o'
164+
'ggml.o' <<
165+
'ggml-alloc.o' <<
166+
'ggml-backend.o' <<
167+
'ggml-quants.o' <<
168+
'ggml-aarch64.o'
194169

195170
$OBJ_WHISPER <<
196-
' whisper.o'
171+
'whisper.o'
197172

198-
$OBJ_ALL = "#{$OBJ_GGML} #{$OBJ_WHISPER} #{$OBJ_COMMON} #{$OBJ_SDL}"
173+
$objs = $OBJ_GGML + $OBJ_WHISPER + $OBJ_COMMON + $OBJ_SDL
174+
$objs << "ruby_whisper.o"
199175

200176
$CPPFLAGS = "#{$MK_CPPFLAGS} #{$CPPFLAGS}"
201177
$CFLAGS = "#{$CPPFLAGS} #{$MK_CFLAGS} #{$GF_CFLAGS} #{$CFLAGS}"
@@ -204,26 +180,13 @@ def with_disabling_unsupported_files
204180
$NVCCFLAGS = "#{$MK_NVCCFLAGS} #{$NVCCFLAGS}"
205181
$LDFLAGS = "#{$MK_LDFLAGS} #{$LDFLAGS}"
206182

207-
if $GGML_METAL_EMBED_LIBRARY
208-
File.write 'depend', "$(OBJS): $(OBJS) ggml-metal-embed.o\n"
209-
end
210-
211-
with_disabling_unsupported_files do
212-
213-
create_makefile('whisper')
214-
215-
end
183+
create_makefile('whisper')
216184

217185
File.open 'Makefile', 'a' do |file|
218186
file.puts 'include get-flags.mk'
219187

220188
if $GGML_METAL
221189
if $GGML_METAL_EMBED_LIBRARY
222-
# mkmf determines object files to compile dependent on existing *.{c,cpp,m} files
223-
# but ggml-metal-embed.c doesn't exist on creating Makefile.
224-
file.puts "objs := $(OBJS)"
225-
file.puts "OBJS = $(objs) 'ggml-metal-embed.o'"
226-
227190
file.puts 'include metal-embed.mk'
228191
end
229192
end

0 commit comments

Comments
 (0)