snapshot of https://github.com/ggml-org/whisper.cpp.git @ da54572229bcf64ba367d96c7ef15770376c4280 (2026-09-15)
Some checks failed
Bindings Tests (Go) / ubuntu-22 (push) Failing after 31s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/ppc64le, icx, icpx, ON) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/ppc64le, icx, icpx, ON) (push) Failing after 3s
CI (vad) / vad (push) Failing after 3s
CI (wasm) / emscripten (Release) (push) Failing after 4s
Bindings Tests (Ruby) / ubuntu-22 (push) Failing after 37s
CI (android) / android (push) Failing after 16s
CI (android) / android_java (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Release) (push) Failing after 2s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Release) (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-low-perf (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-high-perf (push) Failing after 2s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Release) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Release) (push) Failing after 4s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Release) (push) Failing after 3s
CI (quantize) / quantize (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (ADDRESS) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (THREAD) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (UNDEFINED) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm64, icx, icpx, ON) (push) Failing after 3s
Examples WASM / deploy-wasm-github-pages (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (20.x) (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (22.x) (push) Failing after 2s
CI (coreml) / coreml-base-en (push) Has been cancelled
CI (self-hosted) / gpu-vulkan (push) Has been cancelled
CI (self-hosted) / npu-amd-windows (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm2 (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Debug) (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Release) (push) Has been cancelled
CI (self-hosted) / gpu-cuda (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-low-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf-sve (push) Has been cancelled
CI (freebsd) / freeBSD-latest (push) Has been cancelled
CI (self-hosted) / gpu-metal (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Debug) (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Release) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=iOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=macOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=tvOS) (push) Has been cancelled
CI (self-hosted) / npu-amd-linux (push) Has been cancelled
CI (windows) / windows-msys2 (Release, clang, clang-x86_64, CLANG64) (push) Has been cancelled
CI (windows) / windows-msys2 (Release, gcc, ucrt-x86_64, UCRT64) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-cuda.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-cuda]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-intel.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-intel]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-musa.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-musa]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-vulkan]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-vulkan-arm64]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-arm64]) (push) Has been cancelled
Mark inactive issues stale / mark-issues (push) Failing after 1s
Some checks failed
Bindings Tests (Go) / ubuntu-22 (push) Failing after 31s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/ppc64le, icx, icpx, ON) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/ppc64le, icx, icpx, ON) (push) Failing after 3s
CI (vad) / vad (push) Failing after 3s
CI (wasm) / emscripten (Release) (push) Failing after 4s
Bindings Tests (Ruby) / ubuntu-22 (push) Failing after 37s
CI (android) / android (push) Failing after 16s
CI (android) / android_java (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Release) (push) Failing after 2s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Release) (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-low-perf (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-high-perf (push) Failing after 2s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Release) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Release) (push) Failing after 4s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Release) (push) Failing after 3s
CI (quantize) / quantize (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (ADDRESS) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (THREAD) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (UNDEFINED) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm64, icx, icpx, ON) (push) Failing after 3s
Examples WASM / deploy-wasm-github-pages (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (20.x) (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (22.x) (push) Failing after 2s
CI (coreml) / coreml-base-en (push) Has been cancelled
CI (self-hosted) / gpu-vulkan (push) Has been cancelled
CI (self-hosted) / npu-amd-windows (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm2 (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Debug) (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Release) (push) Has been cancelled
CI (self-hosted) / gpu-cuda (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-low-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf-sve (push) Has been cancelled
CI (freebsd) / freeBSD-latest (push) Has been cancelled
CI (self-hosted) / gpu-metal (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Debug) (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Release) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=iOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=macOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=tvOS) (push) Has been cancelled
CI (self-hosted) / npu-amd-linux (push) Has been cancelled
CI (windows) / windows-msys2 (Release, clang, clang-x86_64, CLANG64) (push) Has been cancelled
CI (windows) / windows-msys2 (Release, gcc, ucrt-x86_64, UCRT64) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-cuda.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-cuda]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-intel.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-intel]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-musa.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-musa]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-vulkan]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-vulkan-arm64]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-arm64]) (push) Has been cancelled
Mark inactive issues stale / mark-issues (push) Failing after 1s
This commit is contained in:
26
bindings/ruby/test/helper.rb
Normal file
26
bindings/ruby/test/helper.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
require "test/unit"
|
||||
require "whisper"
|
||||
require_relative "jfk_reader/jfk_reader"
|
||||
|
||||
class TestBase < Test::Unit::TestCase
|
||||
AUDIO = File.join(__dir__, "fixtures", "jfk.wav")
|
||||
|
||||
Parakeet = Whisper::Parakeet
|
||||
|
||||
class << self
|
||||
def whisper
|
||||
return @whisper if @whisper
|
||||
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
params = Whisper::Params.new
|
||||
params.print_timestamps = false
|
||||
@whisper.transcribe(TestBase::AUDIO, params)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def whisper
|
||||
self.class.whisper
|
||||
end
|
||||
end
|
||||
5
bindings/ruby/test/jfk_reader/.gitignore
vendored
Normal file
5
bindings/ruby/test/jfk_reader/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Makefile
|
||||
jfk_reader.o
|
||||
jfk_reader.so
|
||||
jfk_reader.bundle
|
||||
jfk_reader.dll
|
||||
3
bindings/ruby/test/jfk_reader/extconf.rb
Normal file
3
bindings/ruby/test/jfk_reader/extconf.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
require "mkmf"
|
||||
|
||||
create_makefile("jfk_reader")
|
||||
111
bindings/ruby/test/jfk_reader/jfk_reader.c
Normal file
111
bindings/ruby/test/jfk_reader/jfk_reader.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include <ruby.h>
|
||||
#include <ruby/memory_view.h>
|
||||
#include <ruby/encoding.h>
|
||||
|
||||
typedef struct {
|
||||
VALUE audio_path;
|
||||
int n_samples;
|
||||
const char *audio_path_str;
|
||||
float *data;
|
||||
short *samples;
|
||||
} jfk_alloc_args;
|
||||
|
||||
static VALUE
|
||||
jfk_reader_alloc_resources(VALUE arg)
|
||||
{
|
||||
jfk_alloc_args *a = (jfk_alloc_args *)arg;
|
||||
a->audio_path_str = StringValueCStr(a->audio_path);
|
||||
a->data = ALLOC_N(float, a->n_samples);
|
||||
a->samples = ALLOC_N(short, a->n_samples);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
jfk_reader_initialize(VALUE self, VALUE audio_path)
|
||||
{
|
||||
rb_iv_set(self, "audio_path", audio_path);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static bool
|
||||
jfk_reader_get_memory_view(const VALUE obj, rb_memory_view_t *view, int flags)
|
||||
{
|
||||
VALUE audio_path = rb_iv_get(obj, "audio_path");
|
||||
// n_samples is a fixed constant (not derived from user input).
|
||||
const int n_samples = 176000;
|
||||
|
||||
jfk_alloc_args args = {
|
||||
.audio_path = audio_path,
|
||||
.n_samples = n_samples,
|
||||
.audio_path_str = NULL,
|
||||
.data = NULL,
|
||||
.samples = NULL,
|
||||
};
|
||||
|
||||
int state;
|
||||
rb_protect(jfk_reader_alloc_resources, (VALUE)&args, &state);
|
||||
if (state) {
|
||||
if (args.samples) xfree(args.samples);
|
||||
if (args.data) xfree(args.data);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *file = fopen(args.audio_path_str, "rb");
|
||||
if (file == NULL) {
|
||||
xfree(args.samples);
|
||||
xfree(args.data);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(file, 78, SEEK_SET);
|
||||
fread(args.samples, sizeof(short), n_samples, file);
|
||||
fclose(file);
|
||||
for (int i = 0; i < n_samples; i++) {
|
||||
args.data[i] = args.samples[i] / 32768.0;
|
||||
}
|
||||
xfree(args.samples);
|
||||
|
||||
view->obj = obj;
|
||||
view->data = (void *)args.data;
|
||||
view->byte_size = sizeof(float) * n_samples;
|
||||
view->readonly = true;
|
||||
view->format = "e";
|
||||
view->item_size = sizeof(float);
|
||||
view->item_desc.components = NULL;
|
||||
view->item_desc.length = 0;
|
||||
view->ndim = 1;
|
||||
view->shape = NULL;
|
||||
view->sub_offsets = NULL;
|
||||
view->private_data = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
jfk_reader_release_memory_view(const VALUE obj, rb_memory_view_t *view)
|
||||
{
|
||||
if (view->data) {
|
||||
xfree(view->data);
|
||||
view->data = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
jfk_reader_memory_view_available_p(const VALUE obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const rb_memory_view_entry_t jfk_reader_view_entry = {
|
||||
jfk_reader_get_memory_view,
|
||||
jfk_reader_release_memory_view,
|
||||
jfk_reader_memory_view_available_p
|
||||
};
|
||||
|
||||
void Init_jfk_reader(void)
|
||||
{
|
||||
VALUE cJFKReader = rb_define_class("JFKReader", rb_cObject);
|
||||
rb_memory_view_register(cJFKReader, &jfk_reader_view_entry);
|
||||
rb_define_method(cJFKReader, "initialize", jfk_reader_initialize, 1);
|
||||
}
|
||||
203
bindings/ruby/test/test_callback.rb
Normal file
203
bindings/ruby/test/test_callback.rb
Normal file
@@ -0,0 +1,203 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestCallback < TestBase
|
||||
def setup
|
||||
GC.start
|
||||
@params = Whisper::Params.new
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
@audio = File.join(AUDIO)
|
||||
end
|
||||
|
||||
def test_new_segment_callback
|
||||
@params.new_segment_callback = ->(context, state, n_new, user_data) {
|
||||
assert_kind_of Integer, n_new
|
||||
assert n_new > 0
|
||||
assert_same @whisper, context
|
||||
|
||||
n_segments = context.full_n_segments
|
||||
n_new.times do |i|
|
||||
i_segment = n_segments - 1 + i
|
||||
start_time = context.full_get_segment_t0(i_segment) * 10
|
||||
end_time = context.full_get_segment_t1(i_segment) * 10
|
||||
text = context.full_get_segment_text(i_segment)
|
||||
|
||||
assert_kind_of Integer, start_time
|
||||
assert start_time >= 0
|
||||
assert_kind_of Integer, end_time
|
||||
assert end_time > 0
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, text) if i_segment == 0
|
||||
end
|
||||
}
|
||||
|
||||
@whisper.transcribe(@audio, @params)
|
||||
end
|
||||
|
||||
def test_new_segment_callback_closure
|
||||
search_word = "what"
|
||||
@params.new_segment_callback = ->(context, state, n_new, user_data) {
|
||||
n_segments = context.full_n_segments
|
||||
n_new.times do |i|
|
||||
i_segment = n_segments - 1 + i
|
||||
text = context.full_get_segment_text(i_segment)
|
||||
if text.include?(search_word)
|
||||
t0 = context.full_get_segment_t0(i_segment)
|
||||
t1 = context.full_get_segment_t1(i_segment)
|
||||
raise "search word '#{search_word}' found at between #{t0} and #{t1}"
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
assert_raise RuntimeError do
|
||||
@whisper.transcribe(@audio, @params)
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_segment_callback_user_data
|
||||
udata = Object.new
|
||||
@params.new_segment_callback_user_data = udata
|
||||
@params.new_segment_callback = ->(context, state, n_new, user_data) {
|
||||
assert_same udata, user_data
|
||||
}
|
||||
|
||||
@whisper.transcribe(@audio, @params)
|
||||
end
|
||||
|
||||
def test_new_segment_callback_user_data_gc
|
||||
@params.new_segment_callback_user_data = "My user data"
|
||||
@params.new_segment_callback = ->(context, state, n_new, user_data) {
|
||||
assert_equal "My user data", user_data
|
||||
}
|
||||
GC.start
|
||||
|
||||
assert_same @whisper, @whisper.transcribe(@audio, @params)
|
||||
end
|
||||
|
||||
def test_progress_callback
|
||||
first = nil
|
||||
last = nil
|
||||
@params.progress_callback = ->(context, state, progress, user_data) {
|
||||
assert_kind_of Integer, progress
|
||||
assert 0 <= progress && progress <= 100
|
||||
assert_same @whisper, context
|
||||
first = progress if first.nil?
|
||||
last = progress
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert_equal 0, first
|
||||
assert_equal 100, last
|
||||
end
|
||||
|
||||
def test_progress_callback_user_data
|
||||
udata = Object.new
|
||||
@params.progress_callback_user_data = udata
|
||||
@params.progress_callback = ->(context, state, n_new, user_data) {
|
||||
assert_same udata, user_data
|
||||
}
|
||||
|
||||
@whisper.transcribe(@audio, @params)
|
||||
end
|
||||
|
||||
def test_on_progress
|
||||
first = nil
|
||||
last = nil
|
||||
@params.on_progress do |progress|
|
||||
assert_kind_of Integer, progress
|
||||
assert 0 <= progress && progress <= 100
|
||||
first = progress if first.nil?
|
||||
last = progress
|
||||
end
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert_equal 0, first
|
||||
assert_equal 100, last
|
||||
end
|
||||
|
||||
def test_encoder_begin_callback
|
||||
i = 0
|
||||
@params.encoder_begin_callback = ->(context, state, user_data) {
|
||||
i += 1
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert i > 0
|
||||
end
|
||||
|
||||
def test_encoder_begin_callback_abort
|
||||
logs = []
|
||||
Whisper.log_set -> (level, buffer, user_data) {
|
||||
logs << buffer if level == Whisper::LOG_LEVEL_ERROR
|
||||
}, logs
|
||||
@params.encoder_begin_callback = ->(context, state, user_data) {
|
||||
return false
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
sleep 0.5 # wait for logs dequeued
|
||||
assert_match(/encoder_begin_callback returned false - aborting/, logs.join)
|
||||
Whisper.log_set ->(level, buffer, user_data) {}, nil
|
||||
end
|
||||
|
||||
def test_encoder_begin_callback_user_data
|
||||
udata = Object.new
|
||||
@params.encoder_begin_callback_user_data = udata
|
||||
yielded = nil
|
||||
@params.encoder_begin_callback = ->(context, state, user_data) {
|
||||
yielded = user_data
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert_same udata, yielded
|
||||
end
|
||||
|
||||
def test_on_encoder_begin
|
||||
i = 0
|
||||
@params.on_encoder_begin do
|
||||
i += 1
|
||||
end
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert i > 0
|
||||
end
|
||||
|
||||
def test_abort_callback
|
||||
i = 0
|
||||
@params.abort_callback = ->(user_data) {
|
||||
assert_nil user_data
|
||||
i += 1
|
||||
return false
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert i > 0
|
||||
end
|
||||
|
||||
def test_abort_callback_abort
|
||||
i = 0
|
||||
@params.abort_callback = ->(user_data) {
|
||||
i += 1
|
||||
return i == 3
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert_equal 3, i
|
||||
end
|
||||
|
||||
def test_abort_callback_user_data
|
||||
udata = Object.new
|
||||
@params.abort_callback_user_data = udata
|
||||
yielded = nil
|
||||
@params.abort_callback = ->(user_data) {
|
||||
yielded = user_data
|
||||
}
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert_same udata, yielded
|
||||
end
|
||||
|
||||
def test_abort_on
|
||||
do_abort = false
|
||||
_aborted_from_callback = false
|
||||
@params.on_new_segment do |segment|
|
||||
do_abort = true if segment.text.match?(/ask/)
|
||||
end
|
||||
i = 0
|
||||
@params.abort_on do
|
||||
i += 1
|
||||
do_abort
|
||||
end
|
||||
@whisper.transcribe(@audio, @params)
|
||||
assert i > 0
|
||||
end
|
||||
end
|
||||
82
bindings/ruby/test/test_context_params.rb
Normal file
82
bindings/ruby/test/test_context_params.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestContextParams < TestBase
|
||||
PARAM_NAMES = [
|
||||
:use_gpu,
|
||||
:flash_attn,
|
||||
:gpu_device,
|
||||
:dtw_token_timestamps,
|
||||
:dtw_aheads_preset,
|
||||
:dtw_n_top
|
||||
]
|
||||
|
||||
def test_new
|
||||
params = Whisper::Context::Params.new
|
||||
assert_instance_of Whisper::Context::Params, params
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
params = Whisper::Context::Params.new
|
||||
|
||||
assert_true params.use_gpu
|
||||
params.use_gpu = false
|
||||
assert_false params.use_gpu
|
||||
|
||||
assert_true params.flash_attn
|
||||
params.flash_attn = false
|
||||
assert_false params.flash_attn
|
||||
|
||||
assert_equal 0, params.gpu_device
|
||||
params.gpu_device = 1
|
||||
assert_equal 1, params.gpu_device
|
||||
|
||||
assert_false params.dtw_token_timestamps
|
||||
params.dtw_token_timestamps = true
|
||||
assert_true params.dtw_token_timestamps
|
||||
|
||||
assert_equal Whisper::AHEADS_NONE, params.dtw_aheads_preset
|
||||
params.dtw_aheads_preset =Whisper::AHEADS_BASE
|
||||
assert_equal Whisper::AHEADS_BASE, params.dtw_aheads_preset
|
||||
|
||||
assert_nil params.dtw_n_top
|
||||
params.dtw_n_top = 6
|
||||
assert_equal 6, params.dtw_n_top
|
||||
params.dtw_n_top = nil
|
||||
assert_nil params.dtw_n_top
|
||||
end
|
||||
|
||||
def test_new_with_kw_args
|
||||
params = Whisper::Context::Params.new(use_gpu: false)
|
||||
assert_false params.use_gpu
|
||||
end
|
||||
|
||||
def test_new_with_kw_wargs_non_existent
|
||||
assert_raise ArgumentError do
|
||||
Whisper::Context::Params.new(non_existent: "value")
|
||||
end
|
||||
end
|
||||
|
||||
data(PARAM_NAMES.collect {|param| [param, param]}.to_h)
|
||||
def test_new_with_kw_args_default_values(param)
|
||||
default_params = Whisper::Context::Params.new
|
||||
default_value = default_params.send(param)
|
||||
value = if param == :dtw_n_top
|
||||
6
|
||||
else
|
||||
case default_value
|
||||
in true | false
|
||||
!default_value
|
||||
in Integer
|
||||
default_value + 1
|
||||
end
|
||||
end
|
||||
params = Whisper::Context::Params.new(param => value)
|
||||
assert_equal value, params.send(param)
|
||||
|
||||
PARAM_NAMES.reject {|name| name == param}.each do |name|
|
||||
expected = default_params.send(name)
|
||||
actual = params.send(name)
|
||||
assert_equal expected, actual
|
||||
end
|
||||
end
|
||||
end
|
||||
20
bindings/ruby/test/test_error.rb
Normal file
20
bindings/ruby/test/test_error.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestError < TestBase
|
||||
def test_error
|
||||
error = Whisper::Error.new(-2)
|
||||
assert_equal "failed to compute log mel spectrogram", error.message
|
||||
assert_equal(-2, error.code)
|
||||
end
|
||||
|
||||
def test_unknown_error
|
||||
error = Whisper::Error.new(-20)
|
||||
assert_equal "unknown error", error.message
|
||||
end
|
||||
|
||||
def test_non_int_code
|
||||
assert_raise TypeError do
|
||||
_error = Whisper::Error.new("non int")
|
||||
end
|
||||
end
|
||||
end
|
||||
118
bindings/ruby/test/test_model.rb
Normal file
118
bindings/ruby/test/test_model.rb
Normal file
@@ -0,0 +1,118 @@
|
||||
require_relative "helper"
|
||||
require "pathname"
|
||||
|
||||
class TestModel < TestBase
|
||||
def test_model
|
||||
whisper = Whisper::Context.new("base.en")
|
||||
assert_instance_of Whisper::Model, whisper.model
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
whisper = Whisper::Context.new("base.en")
|
||||
model = whisper.model
|
||||
|
||||
assert_equal 51864, model.n_vocab
|
||||
assert_equal 1500, model.n_audio_ctx
|
||||
assert_equal 512, model.n_audio_state
|
||||
assert_equal 8, model.n_audio_head
|
||||
assert_equal 6, model.n_audio_layer
|
||||
assert_equal 448, model.n_text_ctx
|
||||
assert_equal 512, model.n_text_state
|
||||
assert_equal 8, model.n_text_head
|
||||
assert_equal 6, model.n_text_layer
|
||||
assert_equal 80, model.n_mels
|
||||
assert_equal 1, model.ftype
|
||||
assert_equal "base", model.type
|
||||
end
|
||||
|
||||
def test_gc
|
||||
model = Whisper::Context.new("base.en").model
|
||||
GC.start
|
||||
|
||||
assert_equal 51864, model.n_vocab
|
||||
assert_equal 1500, model.n_audio_ctx
|
||||
assert_equal 512, model.n_audio_state
|
||||
assert_equal 8, model.n_audio_head
|
||||
assert_equal 6, model.n_audio_layer
|
||||
assert_equal 448, model.n_text_ctx
|
||||
assert_equal 512, model.n_text_state
|
||||
assert_equal 8, model.n_text_head
|
||||
assert_equal 6, model.n_text_layer
|
||||
assert_equal 80, model.n_mels
|
||||
assert_equal 1, model.ftype
|
||||
assert_equal "base", model.type
|
||||
end
|
||||
|
||||
def test_pathname
|
||||
path = Pathname(Whisper::Model.pre_converted_models["base.en"].to_path)
|
||||
whisper = Whisper::Context.new(path)
|
||||
model = whisper.model
|
||||
|
||||
assert_equal 51864, model.n_vocab
|
||||
assert_equal 1500, model.n_audio_ctx
|
||||
assert_equal 512, model.n_audio_state
|
||||
assert_equal 8, model.n_audio_head
|
||||
assert_equal 6, model.n_audio_layer
|
||||
assert_equal 448, model.n_text_ctx
|
||||
assert_equal 512, model.n_text_state
|
||||
assert_equal 8, model.n_text_head
|
||||
assert_equal 6, model.n_text_layer
|
||||
assert_equal 80, model.n_mels
|
||||
assert_equal 1, model.ftype
|
||||
assert_equal "base", model.type
|
||||
end
|
||||
|
||||
def test_auto_download
|
||||
path = Whisper::Model.pre_converted_models["base.en"].to_path
|
||||
|
||||
assert_path_exist path
|
||||
assert_equal 147964211, File.size(path)
|
||||
end
|
||||
|
||||
def test_uri_string
|
||||
path = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin"
|
||||
whisper = Whisper::Context.new(path)
|
||||
model = whisper.model
|
||||
|
||||
assert_equal 51864, model.n_vocab
|
||||
assert_equal 1500, model.n_audio_ctx
|
||||
assert_equal 512, model.n_audio_state
|
||||
assert_equal 8, model.n_audio_head
|
||||
assert_equal 6, model.n_audio_layer
|
||||
assert_equal 448, model.n_text_ctx
|
||||
assert_equal 512, model.n_text_state
|
||||
assert_equal 8, model.n_text_head
|
||||
assert_equal 6, model.n_text_layer
|
||||
assert_equal 80, model.n_mels
|
||||
assert_equal 1, model.ftype
|
||||
assert_equal "base", model.type
|
||||
end
|
||||
|
||||
def test_uri
|
||||
path = URI("https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin")
|
||||
whisper = Whisper::Context.new(path)
|
||||
model = whisper.model
|
||||
|
||||
assert_equal 51864, model.n_vocab
|
||||
assert_equal 1500, model.n_audio_ctx
|
||||
assert_equal 512, model.n_audio_state
|
||||
assert_equal 8, model.n_audio_head
|
||||
assert_equal 6, model.n_audio_layer
|
||||
assert_equal 448, model.n_text_ctx
|
||||
assert_equal 512, model.n_text_state
|
||||
assert_equal 8, model.n_text_head
|
||||
assert_equal 6, model.n_text_layer
|
||||
assert_equal 80, model.n_mels
|
||||
assert_equal 1, model.ftype
|
||||
assert_equal "base", model.type
|
||||
end
|
||||
|
||||
def test_coreml_model_auto_download
|
||||
uri = Whisper::Model.coreml_compiled_models[Whisper::Model.pre_converted_models["tiny"]]
|
||||
model_path = Pathname(uri.to_path).sub_ext("")
|
||||
model_path.rmtree if model_path.exist?
|
||||
|
||||
uri.cache
|
||||
assert_path_exist model_path
|
||||
end
|
||||
end
|
||||
52
bindings/ruby/test/test_package.rb
Normal file
52
bindings/ruby/test/test_package.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
require_relative "helper"
|
||||
require 'tempfile'
|
||||
require 'tmpdir'
|
||||
require 'open3'
|
||||
|
||||
class TestPackage < TestBase
|
||||
def test_build
|
||||
Tempfile.create do |file|
|
||||
assert system("gem", "build", "whispercpp.gemspec", "--output", file.to_path, exception: true)
|
||||
assert file.size > 0
|
||||
assert_path_exist file.to_path
|
||||
end
|
||||
end
|
||||
|
||||
sub_test_case "Building binary on installation" do
|
||||
def setup
|
||||
system "rake", "build", exception: true
|
||||
end
|
||||
|
||||
def test_install
|
||||
gemspec = Gem::Specification.load("whispercpp.gemspec")
|
||||
Dir.mktmpdir do |dir|
|
||||
system "gem", "install", "--install-dir", dir, "--no-document", File.join("pkg", gemspec.file_name), exception: true
|
||||
assert_installed dir, gemspec.version
|
||||
end
|
||||
end
|
||||
|
||||
def test_install_with_coreml
|
||||
omit_unless RUBY_PLATFORM.match?(/darwin/) do
|
||||
gemspec = Gem::Specification.load("whispercpp.gemspec")
|
||||
Dir.mktmpdir do |dir|
|
||||
system "gem", "install", "--install-dir", dir, "--no-document", File.join("pkg", gemspec.file_name), "--", "--enable-whisper-coreml", exception: true
|
||||
assert_installed dir, gemspec.version
|
||||
libdir = File.join(dir, "gems", "#{gemspec.name}-#{gemspec.version}", "lib")
|
||||
assert_nothing_raised do
|
||||
system "ruby", "-I", libdir, "-r", "whisper", "-e", "Whisper::Context.new('tiny')", exception: true
|
||||
end
|
||||
output, status = Open3.capture2("ruby", "-I", libdir, "-r", "whisper", "-e", "puts Whisper.system_info_str")
|
||||
assert_match /COREML = 1/, output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_installed(dir, version)
|
||||
assert_path_exist File.join(dir, "gems/whispercpp-#{version}/lib", "whisper.#{RbConfig::CONFIG["DLEXT"]}")
|
||||
assert_path_exist File.join(dir, "gems/whispercpp-#{version}/LICENSE")
|
||||
assert_path_not_exist File.join(dir, "gems/whispercpp-#{version}/ext/build")
|
||||
end
|
||||
end
|
||||
end
|
||||
28
bindings/ruby/test/test_parakeet.rb
Normal file
28
bindings/ruby/test/test_parakeet.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
require_relative "helper"
|
||||
require "stringio"
|
||||
|
||||
class TestParakeet < TestBase
|
||||
def test_log_set
|
||||
log_callback = Parakeet.instance_variable_get("@log_callback")
|
||||
user_data = Parakeet.instance_variable_get("@log_callback_user_data")
|
||||
|
||||
$stdout = StringIO.new
|
||||
Parakeet.log_set proc {|level, message, _| puts [level, message].join(": ")}, nil
|
||||
Parakeet::Context.new("test/fixtures/for-tests-ggml-parakeet-tdt.bin")
|
||||
sleep 0.1
|
||||
$stdout.rewind
|
||||
logs = $stdout.string
|
||||
assert_match /loading model from/, logs
|
||||
ensure
|
||||
$stdout = STDOUT
|
||||
Parakeet.log_set log_callback, user_data
|
||||
end
|
||||
|
||||
def test_system_info_str
|
||||
assert_match /\APARAKEET : /, Parakeet.system_info_str
|
||||
end
|
||||
|
||||
def test_version
|
||||
assert_instance_of String, Parakeet::VERSION
|
||||
end
|
||||
end
|
||||
107
bindings/ruby/test/test_parakeet_callback.rb
Normal file
107
bindings/ruby/test/test_parakeet_callback.rb
Normal file
@@ -0,0 +1,107 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParakeetCallback < TestBase
|
||||
def setup
|
||||
omit "Skip not to download large model" if ENV["CI"]
|
||||
|
||||
Whisper.instance_variable_set "@whisper", nil
|
||||
GC.start
|
||||
@params = Parakeet::Params.new
|
||||
@parakeet = Parakeet::Context.new("parakeet-tdt-0.6b-v3-q4_0")
|
||||
end
|
||||
|
||||
def test_new_segment_callback
|
||||
@params.new_segment_callback = ->(context, state, n_new, user_data) {
|
||||
assert_kind_of Integer, n_new
|
||||
assert n_new > 0
|
||||
assert_same @parakeet, context
|
||||
|
||||
n_segments = context.full_n_segments
|
||||
n_new.times do |i|
|
||||
i_segment = n_segments - 1 + i
|
||||
start_time = context.full_get_segment_t0(i_segment) * 10
|
||||
end_time = context.full_get_segment_t1(i_segment) * 10
|
||||
text = context.full_get_segment_text(i_segment)
|
||||
|
||||
assert_kind_of Integer, start_time
|
||||
assert start_time >= 0
|
||||
assert_kind_of Integer, end_time
|
||||
assert end_time > 0
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your/, text) if i_segment == 0
|
||||
end
|
||||
}
|
||||
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
end
|
||||
|
||||
def test_on_new_segment
|
||||
seg = nil
|
||||
index = 0
|
||||
@params.on_new_segment do |segment|
|
||||
assert_instance_of Parakeet::Segment, segment
|
||||
if index == 0
|
||||
seg = segment
|
||||
assert_equal 0, segment.start_time
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your/, segment.text)
|
||||
end
|
||||
index += 1
|
||||
end
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
assert_equal 0, seg.start_time
|
||||
assert_match /ask not what your country can do for you, ask what you can do for your/, seg.text
|
||||
end
|
||||
|
||||
def test_on_new_token
|
||||
index = 0
|
||||
@params.on_new_token do |token|
|
||||
assert_instance_of Parakeet::Token, token
|
||||
if index == 0
|
||||
assert_instance_of Integer, token.start_time
|
||||
assert_match "▁And", token.text
|
||||
end
|
||||
index += 1
|
||||
end
|
||||
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
end
|
||||
|
||||
def test_on_progress
|
||||
first = nil
|
||||
@params.on_progress do |progress|
|
||||
assert_kind_of Integer, progress
|
||||
assert 0 <= progress && progress <= 100
|
||||
first = progress if first.nil?
|
||||
end
|
||||
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
|
||||
assert_equal 0, first
|
||||
end
|
||||
|
||||
def test_on_encoder_begin
|
||||
i = 0
|
||||
@params.on_encoder_begin do
|
||||
i += 1
|
||||
end
|
||||
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
|
||||
assert i > 0
|
||||
end
|
||||
|
||||
def test_abort_on
|
||||
do_abort = false
|
||||
@params.on_new_segment do |segment|
|
||||
do_abort = true if segment.text.match?(/ask/)
|
||||
end
|
||||
i = 0
|
||||
@params.abort_on do
|
||||
i += 1
|
||||
do_abort
|
||||
end
|
||||
|
||||
@parakeet.transcribe(AUDIO, @params) rescue nil
|
||||
|
||||
assert i > 0
|
||||
end
|
||||
end
|
||||
123
bindings/ruby/test/test_parakeet_context.rb
Normal file
123
bindings/ruby/test/test_parakeet_context.rb
Normal file
@@ -0,0 +1,123 @@
|
||||
require_relative "helper"
|
||||
require "stringio"
|
||||
|
||||
class TestParakeetContext < TestBase
|
||||
def setup
|
||||
omit "Skip not to download large model" if ENV["CI"]
|
||||
|
||||
Whisper.instance_variable_set "@whisper", nil
|
||||
GC.start
|
||||
|
||||
@parakeet = Parakeet::Context.new("parakeet-tdt-0.6b-v3-q4_0")
|
||||
@params = Parakeet::Params.new
|
||||
end
|
||||
|
||||
def test_new
|
||||
assert_instance_of Parakeet::Context, @parakeet
|
||||
end
|
||||
|
||||
def test_new_with_params
|
||||
log_callback = Parakeet.instance_variable_get(:@log_callback)
|
||||
user_data = Parakeet.instance_variable_get(:@log_callback_user_data)
|
||||
begin
|
||||
logs = ""
|
||||
Parakeet.log_set proc {|level, message| logs << message}, nil
|
||||
params = Parakeet::Context::Params.new(use_gpu: false)
|
||||
parakeet = Parakeet::Context.new("parakeet-tdt-0.6b-v3-q4_0", params)
|
||||
assert_instance_of Parakeet::Context, parakeet
|
||||
assert_match /use gpu\s+=\s+0/, logs
|
||||
ensure
|
||||
Parakeet.log_set log_callback, user_data
|
||||
end
|
||||
end
|
||||
|
||||
sub_test_case "full" do
|
||||
def setup
|
||||
super
|
||||
@samples = File.read(AUDIO, nil, 78).unpack("s<*").collect {|i| i.to_f / 2**15}
|
||||
end
|
||||
|
||||
def test_full
|
||||
@parakeet.full @params, @samples, @samples.length
|
||||
|
||||
segments = @parakeet.each_segment.to_a
|
||||
assert_equal 1, segments.length
|
||||
assert_match /ask not what your country can do for you, ask what you can do for your/, segments.first.text
|
||||
end
|
||||
|
||||
def test_full_without_length
|
||||
@parakeet.full(@params, @samples)
|
||||
|
||||
segments = @parakeet.each_segment.to_a
|
||||
assert_equal 1, segments.length
|
||||
assert_match /ask not what your country can do for you, ask what you can do for your/, @parakeet.each_segment.first.text
|
||||
end
|
||||
|
||||
def test_full_enumerator
|
||||
samples = @samples.each
|
||||
@parakeet.full @params, samples, @samples.length
|
||||
|
||||
segments = @parakeet.each_segment.to_a
|
||||
assert_equal 1, segments.length
|
||||
assert_match /ask not what your country can do for you, ask what you can do for your/, @parakeet.each_segment.first.text
|
||||
end
|
||||
|
||||
def test_full_enumerator_without_length
|
||||
samples = @samples.each
|
||||
assert_raise ArgumentError do
|
||||
@parakeet.full @params, samples
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_enumerator_with_too_large_length
|
||||
samples = @samples.each.take(10).to_enum
|
||||
assert_raise StopIteration do
|
||||
@parakeet.full @params, samples, 11
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_with_memory_view
|
||||
samples = JFKReader.new(AUDIO)
|
||||
@parakeet.full @params, samples
|
||||
|
||||
segments = @parakeet.each_segment.to_a
|
||||
assert_equal 1, segments.length
|
||||
assert_match /ask not what your country can do for you, ask what you can do for your/, @parakeet.each_segment.first.text
|
||||
end
|
||||
|
||||
def test_full_with_memroy_view_gc
|
||||
samples = JFKReader.new(AUDIO)
|
||||
@parakeet.full(@params, samples)
|
||||
GC.start
|
||||
require "fiddle"
|
||||
Fiddle::MemoryView.export samples do |view|
|
||||
assert_equal 176000, view.to_s.unpack("#{view.format}*").length
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_transcribe
|
||||
assert_nothing_raised do
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
end
|
||||
end
|
||||
|
||||
def test_transcribe_with_pathname
|
||||
assert_nothing_raised do
|
||||
@parakeet.transcribe Pathname(AUDIO), @params
|
||||
end
|
||||
end
|
||||
|
||||
def test_transcribe_with_nothing
|
||||
assert_raise_message(/open/) do
|
||||
@parakeet.transcribe "nothing", @params
|
||||
end
|
||||
end
|
||||
|
||||
def test_free
|
||||
@parakeet.free
|
||||
assert_raise RuntimeError do
|
||||
@parakeet.transcribe AUDIO, @params
|
||||
end
|
||||
end
|
||||
end
|
||||
24
bindings/ruby/test/test_parakeet_context_params.rb
Normal file
24
bindings/ruby/test/test_parakeet_context_params.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParakeetContextParams < TestBase
|
||||
def setup
|
||||
@params = Parakeet::Context::Params.new
|
||||
end
|
||||
|
||||
def test_new
|
||||
assert_instance_of Parakeet::Context::Params, @params
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
assert_true @params.use_gpu
|
||||
assert_instance_of Integer, @params.gpu_device
|
||||
end
|
||||
|
||||
def test_attribute_writer
|
||||
@params.use_gpu = false
|
||||
assert_false @params.use_gpu
|
||||
|
||||
@params.gpu_device = 2
|
||||
assert_equal 2, @params.gpu_device
|
||||
end
|
||||
end
|
||||
21
bindings/ruby/test/test_parakeet_model.rb
Normal file
21
bindings/ruby/test/test_parakeet_model.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParakeetModel < TestBase
|
||||
def test_model
|
||||
parakeet = Parakeet::Context.new("test/fixtures/for-tests-ggml-parakeet-tdt.bin")
|
||||
assert_instance_of Parakeet::Model, parakeet.model
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
parakeet = Parakeet::Context.new("test/fixtures/for-tests-ggml-parakeet-tdt.bin")
|
||||
model = parakeet.model
|
||||
|
||||
assert_equal 10, model.n_vocab
|
||||
assert_equal 3200, model.n_audio_ctx
|
||||
assert_equal 8, model.n_audio_state
|
||||
assert_equal 2, model.n_audio_head
|
||||
assert_equal 1, model.n_audio_layer
|
||||
assert_equal 16, model.n_mels
|
||||
assert_equal 0, model.ftype
|
||||
end
|
||||
end
|
||||
78
bindings/ruby/test/test_parakeet_params.rb
Normal file
78
bindings/ruby/test/test_parakeet_params.rb
Normal file
@@ -0,0 +1,78 @@
|
||||
require_relative "helper"
|
||||
require "etc"
|
||||
|
||||
class TestParakeetParams < TestBase
|
||||
PARAM_NAMES = [
|
||||
:n_threads,
|
||||
:offset_ms,
|
||||
:duration_ms,
|
||||
:no_context,
|
||||
:audio_ctx
|
||||
]
|
||||
|
||||
def setup
|
||||
@params = Parakeet::Params.new
|
||||
end
|
||||
|
||||
def test_new
|
||||
assert_instance_of Parakeet::Params, @params
|
||||
end
|
||||
|
||||
def test_n_threads
|
||||
assert_equal [4, Etc.nprocessors].min, @params.n_threads
|
||||
|
||||
@params.n_threads = 1
|
||||
assert_equal 1, @params.n_threads
|
||||
end
|
||||
|
||||
def test_offset_ms
|
||||
assert_equal 0, @params.offset_ms
|
||||
|
||||
@params.offset_ms = 10_000
|
||||
assert_equal 10_000, @params.offset_ms
|
||||
end
|
||||
|
||||
def test_duration_ms
|
||||
assert_equal 0, @params.duration_ms
|
||||
|
||||
@params.duration_ms = 60_000
|
||||
assert_equal 60_000, @params.duration_ms
|
||||
end
|
||||
|
||||
def test_no_context
|
||||
assert_equal true, @params.no_context
|
||||
|
||||
@params.no_context = false
|
||||
assert_equal false, @params.no_context
|
||||
end
|
||||
|
||||
def test_audio_ctx
|
||||
assert_equal 0, @params.audio_ctx
|
||||
|
||||
@params.audio_ctx = 1
|
||||
assert_equal 1, @params.audio_ctx
|
||||
end
|
||||
|
||||
def test_new_with_kw_args
|
||||
params = Parakeet::Params.new(n_threads: 1)
|
||||
assert_equal 1, params.n_threads
|
||||
assert_equal 0, params.offset_ms
|
||||
end
|
||||
|
||||
data(PARAM_NAMES.collect {|param| [param, param]}.to_h)
|
||||
def test_new_with_kw_args_default_values(param)
|
||||
default_value = @params.send(param)
|
||||
value = case [param, default_value]
|
||||
in [*, true | false]
|
||||
!default_value
|
||||
in [*, Integer]
|
||||
default_value + 1
|
||||
end
|
||||
params = Parakeet::Params.new(param => value)
|
||||
assert_equal value, params.send(param)
|
||||
|
||||
PARAM_NAMES.reject {|name| name == param}.each do |name|
|
||||
assert_equal @params.send(name), params.send(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
42
bindings/ruby/test/test_parakeet_segment.rb
Normal file
42
bindings/ruby/test/test_parakeet_segment.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParakeetSegment < TestBase
|
||||
def setup
|
||||
omit "Skip not to download large model" if ENV["CI"]
|
||||
|
||||
@parakeet = Parakeet::Context.new("parakeet-tdt-0.6b-v3-q4_0")
|
||||
@parakeet.transcribe AUDIO, Parakeet::Params.new
|
||||
end
|
||||
|
||||
def test_segment
|
||||
whole_text = ""
|
||||
@parakeet.each_segment do |segment|
|
||||
assert_instance_of Parakeet::Segment, segment
|
||||
assert_kind_of Integer, segment.start_time
|
||||
assert segment.end_time >= segment.start_time
|
||||
assert_kind_of String, segment.text
|
||||
whole_text << segment.text
|
||||
end
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, whole_text)
|
||||
end
|
||||
|
||||
def test_deconstruct_keys
|
||||
segment = @parakeet.each_segment.first
|
||||
expected = {
|
||||
start_time: segment.start_time,
|
||||
end_time: segment.end_time,
|
||||
text: segment.text
|
||||
}
|
||||
assert_equal expected, segment.deconstruct_keys([:start_time, :end_time, :text])
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_with_nil
|
||||
segment = @parakeet.each_segment.first
|
||||
expected = {
|
||||
start_time: segment.start_time,
|
||||
end_time: segment.end_time,
|
||||
text: segment.text
|
||||
}
|
||||
assert_equal expected, segment.deconstruct_keys(nil)
|
||||
end
|
||||
end
|
||||
73
bindings/ruby/test/test_parakeet_token.rb
Normal file
73
bindings/ruby/test/test_parakeet_token.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParakeetToken < TestBase
|
||||
ATTRS = %i[
|
||||
id
|
||||
duration_idx
|
||||
duration_value
|
||||
frame_index
|
||||
probability
|
||||
log_probability
|
||||
start_time
|
||||
end_time
|
||||
word_start?
|
||||
text
|
||||
]
|
||||
|
||||
def setup
|
||||
omit "Skip not to download large model" if ENV["CI"]
|
||||
|
||||
Whisper.instance_variable_set "@whisper", nil
|
||||
GC.start
|
||||
|
||||
parakeet = Parakeet::Context.new("parakeet-tdt-0.6b-v3-q4_0")
|
||||
params = Parakeet::Params.new
|
||||
parakeet.transcribe AUDIO, params
|
||||
@segment = parakeet.each_segment.first
|
||||
end
|
||||
|
||||
def test_each_token
|
||||
i = 0
|
||||
@segment.each_token do |token|
|
||||
i += 1
|
||||
assert_instance_of Parakeet::Token, token
|
||||
end
|
||||
assert_equal 38, i
|
||||
end
|
||||
|
||||
def test_each_token_without_block
|
||||
assert_instance_of Enumerator, @segment.each_token
|
||||
end
|
||||
|
||||
def test_token
|
||||
token = @segment.each_token.first
|
||||
|
||||
assert_instance_of Parakeet::Token, token
|
||||
assert_instance_of Integer, token.id
|
||||
assert_instance_of Integer, token.duration_idx
|
||||
assert_instance_of Integer, token.duration_value
|
||||
assert_instance_of Integer, token.frame_index
|
||||
assert_instance_of Float, token.probability
|
||||
assert_instance_of Float, token.log_probability
|
||||
assert_instance_of Integer, token.start_time
|
||||
assert_instance_of Integer, token.end_time
|
||||
assert_instance_of String, token.text
|
||||
end
|
||||
|
||||
def test_text
|
||||
assert_equal ["▁And", "▁so", ",", "▁my", "▁f", "ell", "ow", "▁Amer", "ic", "ans", ",", "▁a", "sk", "▁not", "▁what", "▁your", "▁co", "un", "tr", "y", "▁can", "▁do", "▁for", "▁you", ",", "▁a", "sk", "▁what", "▁you", "▁can", "▁do", "▁for", "▁your", "▁co", "un", "tr", "y", "."],
|
||||
@segment.each_token.collect(&:text)
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_with_nil
|
||||
token = @segment.each_token.first
|
||||
expected = ATTRS.collect {|attr| [attr.to_s.sub(/\?\z/, "").intern, token.send(attr)]}.to_h
|
||||
assert_equal expected, token.deconstruct_keys(nil)
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_with_keys
|
||||
token = @segment.each_token.first
|
||||
expected = ATTRS.collect {|attr| [attr.to_s.sub(/\?\z/, "").intern, token.send(attr)]}.to_h
|
||||
assert_equal expected, token.deconstruct_keys(expected.keys)
|
||||
end
|
||||
end
|
||||
315
bindings/ruby/test/test_params.rb
Normal file
315
bindings/ruby/test/test_params.rb
Normal file
@@ -0,0 +1,315 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestParams < TestBase
|
||||
PARAM_NAMES = [
|
||||
:language,
|
||||
:translate,
|
||||
:no_context,
|
||||
:single_segment,
|
||||
:print_special,
|
||||
:print_progress,
|
||||
:print_realtime,
|
||||
:print_timestamps,
|
||||
:suppress_blank,
|
||||
:suppress_nst,
|
||||
:token_timestamps,
|
||||
:max_len,
|
||||
:split_on_word,
|
||||
:initial_prompt,
|
||||
:carry_initial_prompt,
|
||||
:diarize,
|
||||
:offset,
|
||||
:duration,
|
||||
:max_text_tokens,
|
||||
:temperature,
|
||||
:max_initial_ts,
|
||||
:length_penalty,
|
||||
:temperature_inc,
|
||||
:entropy_thold,
|
||||
:logprob_thold,
|
||||
:no_speech_thold,
|
||||
:new_segment_callback,
|
||||
:new_segment_callback_user_data,
|
||||
:progress_callback,
|
||||
:progress_callback_user_data,
|
||||
:abort_callback,
|
||||
:abort_callback_user_data,
|
||||
:vad,
|
||||
:vad_model_path,
|
||||
:vad_params,
|
||||
]
|
||||
|
||||
def setup
|
||||
@params = Whisper::Params.new
|
||||
end
|
||||
|
||||
def test_language
|
||||
@params.language = "en"
|
||||
assert_equal @params.language, "en"
|
||||
GC.compact
|
||||
assert_equal @params.language, "en"
|
||||
@params.language = "auto"
|
||||
assert_equal @params.language, "auto"
|
||||
end
|
||||
|
||||
def test_offset
|
||||
@params.offset = 10_000
|
||||
assert_equal @params.offset, 10_000
|
||||
@params.offset = 0
|
||||
assert_equal @params.offset, 0
|
||||
end
|
||||
|
||||
def test_duration
|
||||
@params.duration = 60_000
|
||||
assert_equal @params.duration, 60_000
|
||||
@params.duration = 0
|
||||
assert_equal @params.duration, 0
|
||||
end
|
||||
|
||||
def test_max_text_tokens
|
||||
@params.max_text_tokens = 300
|
||||
assert_equal @params.max_text_tokens, 300
|
||||
@params.max_text_tokens = 0
|
||||
assert_equal @params.max_text_tokens, 0
|
||||
end
|
||||
|
||||
def test_translate
|
||||
@params.translate = true
|
||||
assert @params.translate
|
||||
@params.translate = false
|
||||
assert !@params.translate
|
||||
end
|
||||
|
||||
def test_no_context
|
||||
@params.no_context = true
|
||||
assert @params.no_context
|
||||
@params.no_context = false
|
||||
assert !@params.no_context
|
||||
end
|
||||
|
||||
def test_single_segment
|
||||
@params.single_segment = true
|
||||
assert @params.single_segment
|
||||
@params.single_segment = false
|
||||
assert !@params.single_segment
|
||||
end
|
||||
|
||||
def test_print_special
|
||||
@params.print_special = true
|
||||
assert @params.print_special
|
||||
@params.print_special = false
|
||||
assert !@params.print_special
|
||||
end
|
||||
|
||||
def test_print_progress
|
||||
@params.print_progress = true
|
||||
assert @params.print_progress
|
||||
@params.print_progress = false
|
||||
assert !@params.print_progress
|
||||
end
|
||||
|
||||
def test_print_realtime
|
||||
@params.print_realtime = true
|
||||
assert @params.print_realtime
|
||||
@params.print_realtime = false
|
||||
assert !@params.print_realtime
|
||||
end
|
||||
|
||||
def test_print_timestamps
|
||||
@params.print_timestamps = true
|
||||
assert @params.print_timestamps
|
||||
@params.print_timestamps = false
|
||||
assert !@params.print_timestamps
|
||||
end
|
||||
|
||||
def test_carry_initial_prompt
|
||||
@params.carry_initial_prompt = true
|
||||
assert @params.carry_initial_prompt
|
||||
@params.carry_initial_prompt = false
|
||||
assert !@params.carry_initial_prompt
|
||||
end
|
||||
|
||||
def test_suppress_blank
|
||||
@params.suppress_blank = true
|
||||
assert @params.suppress_blank
|
||||
@params.suppress_blank = false
|
||||
assert !@params.suppress_blank
|
||||
end
|
||||
|
||||
def test_suppress_nst
|
||||
@params.suppress_nst = true
|
||||
assert @params.suppress_nst
|
||||
@params.suppress_nst = false
|
||||
assert !@params.suppress_nst
|
||||
end
|
||||
|
||||
def test_token_timestamps
|
||||
@params.token_timestamps = true
|
||||
assert @params.token_timestamps
|
||||
@params.token_timestamps = false
|
||||
assert !@params.token_timestamps
|
||||
end
|
||||
|
||||
def test_max_len
|
||||
@params.max_len = 42
|
||||
assert_equal @params.max_len, 42
|
||||
@params.max_len = 0
|
||||
assert_equal @params.max_len, 0
|
||||
end
|
||||
|
||||
def test_split_on_word
|
||||
@params.split_on_word = true
|
||||
assert @params.split_on_word
|
||||
@params.split_on_word = false
|
||||
assert !@params.split_on_word
|
||||
end
|
||||
|
||||
def test_initial_prompt
|
||||
assert_nil @params.initial_prompt
|
||||
@params.initial_prompt = "You are a polite person."
|
||||
assert_equal "You are a polite person.", @params.initial_prompt
|
||||
end
|
||||
|
||||
def test_temperature
|
||||
assert_equal 0.0, @params.temperature
|
||||
@params.temperature = 0.5
|
||||
assert_equal 0.5, @params.temperature
|
||||
end
|
||||
|
||||
def test_max_initial_ts
|
||||
assert_equal 1.0, @params.max_initial_ts
|
||||
@params.max_initial_ts = 600.0
|
||||
assert_equal 600.0, @params.max_initial_ts
|
||||
end
|
||||
|
||||
def test_length_penalty
|
||||
assert_equal(-1.0, @params.length_penalty)
|
||||
@params.length_penalty = 0.5
|
||||
assert_equal 0.5, @params.length_penalty
|
||||
end
|
||||
|
||||
def test_temperature_inc
|
||||
assert_in_delta 0.2, @params.temperature_inc
|
||||
@params.temperature_inc = 0.5
|
||||
assert_in_delta 0.5, @params.temperature_inc
|
||||
end
|
||||
|
||||
def test_entropy_thold
|
||||
assert_in_delta 2.4, @params.entropy_thold
|
||||
@params.entropy_thold = 3.0
|
||||
assert_in_delta 3.0, @params.entropy_thold
|
||||
end
|
||||
|
||||
def test_logprob_thold
|
||||
assert_in_delta(-1.0, @params.logprob_thold)
|
||||
@params.logprob_thold = -0.5
|
||||
assert_in_delta(-0.5, @params.logprob_thold)
|
||||
end
|
||||
|
||||
def test_no_speech_thold
|
||||
assert_in_delta 0.6, @params.no_speech_thold
|
||||
@params.no_speech_thold = 0.2
|
||||
assert_in_delta 0.2, @params.no_speech_thold
|
||||
end
|
||||
|
||||
def test_vad
|
||||
assert_false @params.vad
|
||||
@params.vad = true
|
||||
assert_true @params.vad
|
||||
end
|
||||
|
||||
def test_vad_model_path
|
||||
assert_nil @params.vad_model_path
|
||||
@params.vad_model_path = "silero-v6.2.0"
|
||||
assert_equal Whisper::Model.pre_converted_models["silero-v6.2.0"].to_path, @params.vad_model_path
|
||||
end
|
||||
|
||||
def test_vad_model_path_with_nil
|
||||
@params.vad_model_path = "silero-v6.2.0"
|
||||
@params.vad_model_path = nil
|
||||
assert_nil @params.vad_model_path
|
||||
end
|
||||
|
||||
def test_vad_model_path_with_invalid
|
||||
assert_raise TypeError do
|
||||
@params.vad_model_path = Object.new
|
||||
end
|
||||
end
|
||||
|
||||
def test_vad_model_path_with_URI_string
|
||||
@params.vad_model_path = "https://huggingface.co/ggml-org/whisper-vad/resolve/main/ggml-silero-v6.2.0.bin"
|
||||
assert_equal @params.vad_model_path, Whisper::Model.pre_converted_models["silero-v6.2.0"].to_path
|
||||
end
|
||||
|
||||
def test_vad_model_path_with_URI
|
||||
@params.vad_model_path = URI("https://huggingface.co/ggml-org/whisper-vad/resolve/main/ggml-silero-v6.2.0.bin")
|
||||
assert_equal @params.vad_model_path, Whisper::Model.pre_converted_models["silero-v6.2.0"].to_path
|
||||
end
|
||||
|
||||
def test_vad_params
|
||||
assert_kind_of Whisper::VAD::Params, @params.vad_params
|
||||
default_params = @params.vad_params
|
||||
assert_same default_params, @params.vad_params
|
||||
assert_equal 0.5, default_params.threshold
|
||||
new_params = Whisper::VAD::Params.new
|
||||
@params.vad_params = new_params
|
||||
assert_same new_params, @params.vad_params
|
||||
end
|
||||
|
||||
def test_new_with_kw_args
|
||||
params = Whisper::Params.new(language: "es")
|
||||
assert_equal "es", params.language
|
||||
assert_equal 1.0, params.max_initial_ts
|
||||
end
|
||||
|
||||
def test_new_with_kw_args_non_existent
|
||||
assert_raise ArgumentError do
|
||||
Whisper::Params.new(non_existent: "value")
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_with_kw_args_wrong_type
|
||||
assert_raise TypeError do
|
||||
Whisper::Params.new(language: 3)
|
||||
end
|
||||
end
|
||||
|
||||
data(PARAM_NAMES.collect {|param| [param, param]}.to_h)
|
||||
def test_new_with_kw_args_default_values(param)
|
||||
default_value = @params.send(param)
|
||||
value = case [param, default_value]
|
||||
in [*, true | false]
|
||||
!default_value
|
||||
in [*, Integer | Float]
|
||||
default_value + 1
|
||||
in [:language, *]
|
||||
"es"
|
||||
in [:initial_prompt, *]
|
||||
"Initial prompt"
|
||||
in [/_callback\Z/, *]
|
||||
proc {}
|
||||
in [/_user_data\Z/, *]
|
||||
Object.new
|
||||
in [:vad_model_path, *]
|
||||
Whisper::Model.pre_converted_models["silero-v6.2.0"].to_path
|
||||
in [:vad_params, *]
|
||||
Whisper::VAD::Params.new
|
||||
end
|
||||
params = Whisper::Params.new(param => value)
|
||||
if Float === value
|
||||
assert_in_delta value, params.send(param)
|
||||
else
|
||||
assert_equal value, params.send(param)
|
||||
end
|
||||
|
||||
PARAM_NAMES.reject {|name| name == param}.each do |name|
|
||||
expected = @params.send(name)
|
||||
actual = params.send(name)
|
||||
if Float === expected
|
||||
assert_in_delta expected, actual
|
||||
else
|
||||
assert_equal expected, actual
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
145
bindings/ruby/test/test_segment.rb
Normal file
145
bindings/ruby/test/test_segment.rb
Normal file
@@ -0,0 +1,145 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestSegment < TestBase
|
||||
def test_iteration
|
||||
whisper.each_segment do |segment|
|
||||
assert_instance_of Whisper::Segment, segment
|
||||
end
|
||||
end
|
||||
|
||||
def test_enumerator
|
||||
enum = whisper.each_segment
|
||||
assert_instance_of Enumerator, enum
|
||||
enum.to_a.each_with_index do |segment, index|
|
||||
assert_instance_of Whisper::Segment, segment
|
||||
assert_kind_of Integer, index
|
||||
end
|
||||
end
|
||||
|
||||
def test_start_time
|
||||
i = 0
|
||||
whisper.each_segment do |segment|
|
||||
assert_equal 0, segment.start_time if i == 0
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
def test_end_time
|
||||
i = 0
|
||||
whisper.each_segment do |segment|
|
||||
assert_equal whisper.full_get_segment_t1(i) * 10, segment.end_time
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
def test_no_speech_prob
|
||||
no_speech_prob = nil
|
||||
whisper.each_segment do |segment|
|
||||
no_speech_prob = segment.no_speech_prob
|
||||
end
|
||||
assert no_speech_prob > 0.0
|
||||
end
|
||||
|
||||
def test_on_new_segment
|
||||
params = Whisper::Params.new
|
||||
seg = nil
|
||||
index = 0
|
||||
params.on_new_segment do |segment|
|
||||
assert_instance_of Whisper::Segment, segment
|
||||
if index == 0
|
||||
seg = segment
|
||||
assert_equal 0, segment.start_time
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, segment.text)
|
||||
end
|
||||
index += 1
|
||||
end
|
||||
whisper.transcribe(AUDIO, params)
|
||||
assert_equal 0, seg.start_time
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, seg.text)
|
||||
end
|
||||
|
||||
def test_on_new_segment_twice
|
||||
params = Whisper::Params.new
|
||||
seg = nil
|
||||
params.on_new_segment do |segment|
|
||||
seg = segment
|
||||
return
|
||||
end
|
||||
params.on_new_segment do |segment|
|
||||
assert_same seg, segment
|
||||
return
|
||||
end
|
||||
whisper.transcribe(AUDIO, params)
|
||||
end
|
||||
|
||||
def test_transcription_after_segment_retrieved
|
||||
segment = whisper.each_segment.first
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, segment.text)
|
||||
|
||||
whisper.transcribe(AUDIO, Whisper::Params.new(offset: 5000))
|
||||
assert_not_match(/ask not what your country can do for you, ask what you can do for your country/, segment.text)
|
||||
assert_match(/what you can do for your country/i, segment.text)
|
||||
end
|
||||
|
||||
def test_pattern_matching
|
||||
segment = whisper.each_segment.first
|
||||
segment => {start_time:, end_time:, text:, no_speech_prob:, speaker_turn_next:}
|
||||
|
||||
assert_equal segment.start_time, start_time
|
||||
assert_equal segment.end_time, end_time
|
||||
assert_equal segment.text, text
|
||||
assert_equal segment.no_speech_prob, no_speech_prob
|
||||
assert_equal segment.speaker_turn_next?, speaker_turn_next
|
||||
end
|
||||
|
||||
def test_pattern_matching_partial
|
||||
segment = whisper.each_segment.first
|
||||
segment => {start_time:, end_time:, text:}
|
||||
|
||||
assert_equal segment.start_time, start_time
|
||||
assert_equal segment.end_time, end_time
|
||||
assert_equal segment.text, text
|
||||
end
|
||||
|
||||
def test_deconstruct_keys
|
||||
segment = whisper.each_segment.first
|
||||
expected = {
|
||||
start_time: segment.start_time,
|
||||
end_time: segment.end_time,
|
||||
text: segment.text,
|
||||
no_speech_prob: segment.no_speech_prob,
|
||||
speaker_turn_next: segment.speaker_turn_next?
|
||||
}
|
||||
assert_equal expected, segment.deconstruct_keys([:start_time, :end_time, :text, :no_speech_prob, :speaker_turn_next])
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_non_existent
|
||||
omit "Undefined behavior"
|
||||
|
||||
segment = whisper.each_segment.first
|
||||
|
||||
assert_equal({}, segment.deconstruct_keys([:non_existent]))
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_too_many_keys
|
||||
omit "Undefined behavior"
|
||||
|
||||
segment = whisper.each_segment.first
|
||||
|
||||
assert_equal({}, segment.deconstruct_keys([:start_time, :end_time, :text, :no_speech_prob, :speaker_turn_next, :extra_key]))
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_includes_non_existent_keys_not_too_many
|
||||
omit "Undefined behavior"
|
||||
|
||||
segment = whisper.each_segment.first
|
||||
|
||||
expected = {
|
||||
start_time: segment.start_time,
|
||||
end_time: segment.end_time,
|
||||
text: segment.text,
|
||||
no_speech_prob: segment.no_speech_prob
|
||||
}
|
||||
assert_equal(expected, segment.deconstruct_keys([:start_time, :end_time, :text, :no_speech_prob, :non_existent]))
|
||||
end
|
||||
end
|
||||
81
bindings/ruby/test/test_token.rb
Normal file
81
bindings/ruby/test/test_token.rb
Normal file
@@ -0,0 +1,81 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestToken < TestBase
|
||||
def setup
|
||||
@segment = whisper.each_segment.first
|
||||
@token = @segment.each_token.first
|
||||
end
|
||||
|
||||
def test_n_tokens
|
||||
assert_equal 27, @segment.n_tokens
|
||||
end
|
||||
|
||||
def test_allocate
|
||||
token = Whisper::Token.allocate
|
||||
assert_raise do
|
||||
token.id
|
||||
end
|
||||
end
|
||||
|
||||
def test_each_token
|
||||
i = 0
|
||||
@segment.each_token do |token|
|
||||
i += 1
|
||||
assert_instance_of Whisper::Token, token
|
||||
end
|
||||
assert_equal 27, i
|
||||
end
|
||||
|
||||
def test_each_token_without_block
|
||||
assert_instance_of Enumerator, @segment.each_token
|
||||
end
|
||||
|
||||
def test_token
|
||||
assert_instance_of Whisper::Token, @token
|
||||
|
||||
assert_instance_of Integer, @token.id
|
||||
assert_instance_of Float, @token.probability
|
||||
assert_instance_of Float, @token.log_probability
|
||||
|
||||
assert_instance_of Integer, @token.tid
|
||||
assert_instance_of Float, @token.pt
|
||||
assert_instance_of Float, @token.ptsum
|
||||
|
||||
assert_instance_of Integer, @token.start_time
|
||||
assert_instance_of Integer, @token.end_time
|
||||
|
||||
assert_instance_of Integer, @token.t_dtw
|
||||
|
||||
assert_instance_of Float, @token.voice_length
|
||||
|
||||
assert_instance_of String, @token.text
|
||||
end
|
||||
|
||||
def test_text
|
||||
assert_equal ["[_BEG_]", " And", " so", " my", " fellow", " Americans", ",", " ask", " not", " what", " your", " country", " can", " do", " for", " you", ",", " ask", " what", " you", " can", " do", " for", " your", " country", ".", "[_TT_550]"],
|
||||
@segment.each_token.collect(&:text)
|
||||
end
|
||||
|
||||
def test_token_timestamps
|
||||
params = Whisper::Params.new(token_timestamps: true)
|
||||
whisper.transcribe(TestBase::AUDIO, params)
|
||||
prev = -1
|
||||
whisper.each_segment.first.each_token do |token|
|
||||
assert token.start_time >= prev
|
||||
assert token.end_time >= token.start_time
|
||||
prev = token.end_time
|
||||
end
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_with_nil
|
||||
keys = %i[id tid probability log_probability pt ptsum t_dtw voice_length start_time end_time text]
|
||||
expected = keys.collect {|key| [key, @token.send(key)] }.to_h
|
||||
assert_equal(expected, @token.deconstruct_keys(nil))
|
||||
end
|
||||
|
||||
def test_deconstruct_keys_with_keys
|
||||
keys = %i[id tid probability log_probability pt ptsum t_dtw voice_length start_time end_time text]
|
||||
expected = keys.collect {|key| [key, @token.send(key)] }.to_h
|
||||
assert_equal expected, @token.deconstruct_keys(keys)
|
||||
end
|
||||
end
|
||||
28
bindings/ruby/test/test_vad.rb
Normal file
28
bindings/ruby/test/test_vad.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestVAD < TestBase
|
||||
def setup
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
vad_params = Whisper::VAD::Params.new
|
||||
@params = Whisper::Params.new(
|
||||
vad: true,
|
||||
vad_model_path: "silero-v6.2.0",
|
||||
vad_params:
|
||||
)
|
||||
end
|
||||
|
||||
def test_transcribe
|
||||
@whisper.transcribe(TestBase::AUDIO, @params) do |text|
|
||||
assert_match(/ask not what your country can do for you[,.] ask what you can do for your country/i, text)
|
||||
end
|
||||
end
|
||||
|
||||
def test_vad_segments_api
|
||||
@whisper.transcribe TestBase::AUDIO, @params
|
||||
|
||||
assert_equal 4, @whisper.full_n_vad_segments
|
||||
@whisper.full_n_vad_segments.times do |i|
|
||||
assert @whisper.full_get_vad_segment_t0(i) < @whisper.full_get_vad_segment_t1(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
108
bindings/ruby/test/test_vad_context.rb
Normal file
108
bindings/ruby/test/test_vad_context.rb
Normal file
@@ -0,0 +1,108 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestVADContext < TestBase
|
||||
def test_initialize
|
||||
context = Whisper::VAD::Context.new("silero-v6.2.0")
|
||||
assert_instance_of Whisper::VAD::Context, context
|
||||
end
|
||||
|
||||
def test_detect
|
||||
context = Whisper::VAD::Context.new("silero-v6.2.0")
|
||||
segments = context.detect(AUDIO, Whisper::VAD::Params.new)
|
||||
assert_segments segments
|
||||
end
|
||||
|
||||
def test_invalid_model_type
|
||||
assert_raise TypeError do
|
||||
Whisper::VAD::Context.new(Object.new)
|
||||
end
|
||||
end
|
||||
|
||||
def test_allocate
|
||||
vad = Whisper::VAD::Context.allocate
|
||||
assert_raise do
|
||||
vad.detect(AUDIO, Whisper::VAD::Params.new)
|
||||
end
|
||||
end
|
||||
|
||||
def test_free
|
||||
vad = Whisper::VAD::Context.new("silero-v6.2.0")
|
||||
vad.free
|
||||
assert_raise RuntimeError do
|
||||
vad.detect(AUDIO, Whisper::VAD::Params.new)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_segments(segments)
|
||||
assert_instance_of Whisper::VAD::Segments, segments
|
||||
|
||||
i = 0
|
||||
segments.each do |segment|
|
||||
i += 1
|
||||
assert_instance_of Whisper::VAD::Segment, segment
|
||||
end
|
||||
assert i > 0
|
||||
|
||||
segments.each_with_index do |segment, index|
|
||||
assert_instance_of Integer, index
|
||||
end
|
||||
|
||||
assert_instance_of Enumerator, segments.each
|
||||
|
||||
segment = segments.each.first
|
||||
assert_instance_of Integer, segment.start_time
|
||||
assert_instance_of Integer, segment.end_time
|
||||
|
||||
segment => {start_time:, end_time:}
|
||||
assert_equal segment.start_time, start_time
|
||||
assert_equal segment.end_time, end_time
|
||||
|
||||
assert_equal 4, segments.length
|
||||
end
|
||||
|
||||
sub_test_case "from samples" do
|
||||
def setup
|
||||
super
|
||||
@vad = Whisper::VAD::Context.new("silero-v6.2.0")
|
||||
@samples = File.read(AUDIO, nil, 78).unpack("s<*").collect {|i| i.to_f / 2**15}
|
||||
end
|
||||
|
||||
def test_segments_from_samples
|
||||
segments = @vad.segments_from_samples(Whisper::VAD::Params.new, @samples, @samples.length)
|
||||
assert_segments segments
|
||||
end
|
||||
|
||||
def test_segments_from_samples_without_length
|
||||
segments = @vad.segments_from_samples(Whisper::VAD::Params.new, @samples)
|
||||
assert_segments segments
|
||||
end
|
||||
|
||||
def test_segments_from_samples_enumerator
|
||||
samples = @samples.each
|
||||
segments = @vad.segments_from_samples(Whisper::VAD::Params.new, samples, @samples.length)
|
||||
assert_segments segments
|
||||
end
|
||||
|
||||
def test_segments_from_samples_enumerator_without_length
|
||||
samples = @samples.each
|
||||
assert_raise ArgumentError do
|
||||
@vad.segments_from_samples(Whisper::VAD::Params.new, samples)
|
||||
end
|
||||
end
|
||||
|
||||
def test_segments_from_samples_enumerator_with_too_large_length
|
||||
samples = @samples.each.take(10).to_enum
|
||||
assert_raise StopIteration do
|
||||
@vad.segments_from_samples(Whisper::VAD::Params.new, samples, 11)
|
||||
end
|
||||
end
|
||||
|
||||
def test_segments_from_samples_with_memory_view
|
||||
samples = JFKReader.new(AUDIO)
|
||||
segments = @vad.segments_from_samples(Whisper::VAD::Params.new, samples)
|
||||
assert_segments segments
|
||||
end
|
||||
end
|
||||
end
|
||||
103
bindings/ruby/test/test_vad_params.rb
Normal file
103
bindings/ruby/test/test_vad_params.rb
Normal file
@@ -0,0 +1,103 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestVADParams < TestBase
|
||||
PARAM_NAMES = [
|
||||
:threshold,
|
||||
:min_speech_duration_ms,
|
||||
:min_silence_duration_ms,
|
||||
:max_speech_duration_s,
|
||||
:speech_pad_ms,
|
||||
:samples_overlap
|
||||
]
|
||||
|
||||
def setup
|
||||
@params = Whisper::VAD::Params.new
|
||||
end
|
||||
|
||||
def test_new
|
||||
params = Whisper::VAD::Params.new
|
||||
assert_kind_of Whisper::VAD::Params, params
|
||||
end
|
||||
|
||||
def test_threshold
|
||||
assert_in_delta @params.threshold, 0.5
|
||||
@params.threshold = 0.7
|
||||
assert_in_delta @params.threshold, 0.7
|
||||
end
|
||||
|
||||
def test_min_speech_duration
|
||||
pend
|
||||
end
|
||||
|
||||
def test_min_speech_duration_ms
|
||||
assert_equal 250, @params.min_speech_duration_ms
|
||||
@params.min_speech_duration_ms = 500
|
||||
assert_equal 500, @params.min_speech_duration_ms
|
||||
end
|
||||
|
||||
def test_min_silence_duration_ms
|
||||
assert_equal 100, @params.min_silence_duration_ms
|
||||
@params.min_silence_duration_ms = 200
|
||||
assert_equal 200, @params.min_silence_duration_ms
|
||||
end
|
||||
|
||||
def test_max_speech_duration
|
||||
pend
|
||||
end
|
||||
|
||||
def test_max_speech_duration_s
|
||||
assert @params.max_speech_duration_s >= 10e37 # Defaults to FLT_MAX
|
||||
@params.max_speech_duration_s = 60.0
|
||||
assert_equal 60.0, @params.max_speech_duration_s
|
||||
end
|
||||
|
||||
def test_speech_pad_ms
|
||||
assert_equal 30, @params.speech_pad_ms
|
||||
@params.speech_pad_ms = 50
|
||||
assert_equal 50, @params.speech_pad_ms
|
||||
end
|
||||
|
||||
def test_samples_overlap
|
||||
assert_in_delta @params.samples_overlap, 0.1
|
||||
@params.samples_overlap = 0.5
|
||||
assert_in_delta @params.samples_overlap, 0.5
|
||||
end
|
||||
|
||||
def test_equal
|
||||
assert_equal @params, Whisper::VAD::Params.new
|
||||
end
|
||||
|
||||
def test_new_with_kw_args
|
||||
params = Whisper::VAD::Params.new(threshold: 0.7)
|
||||
assert_in_delta params.threshold, 0.7
|
||||
assert_equal 250, params.min_speech_duration_ms
|
||||
end
|
||||
|
||||
def test_new_with_kw_args_non_existent
|
||||
assert_raise ArgumentError do
|
||||
Whisper::VAD::Params.new(non_existent: "value")
|
||||
end
|
||||
end
|
||||
|
||||
data(PARAM_NAMES.collect {|param| [param, param]}.to_h)
|
||||
def test_new_with_kw_args_default_values(param)
|
||||
default_value = @params.send(param)
|
||||
value = default_value + 1
|
||||
params = Whisper::VAD::Params.new(param => value)
|
||||
if Float === value
|
||||
assert_in_delta value, params.send(param)
|
||||
else
|
||||
assert_equal value, params.send(param)
|
||||
end
|
||||
|
||||
PARAM_NAMES.reject {|name| name == param}.each do |name|
|
||||
expected = @params.send(name)
|
||||
actual = params.send(name)
|
||||
if Float === expected
|
||||
assert_in_delta expected, actual
|
||||
else
|
||||
assert_equal expected, actual
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
19
bindings/ruby/test/test_vad_segment.rb
Normal file
19
bindings/ruby/test/test_vad_segment.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestVADSegment < TestBase
|
||||
def test_initialize
|
||||
segment = Whisper::VAD::Segment.new
|
||||
|
||||
assert_raise do
|
||||
segment.start_time
|
||||
end
|
||||
|
||||
assert_raise do
|
||||
segment.end_time
|
||||
end
|
||||
|
||||
assert_raise do
|
||||
segment => {start_time:, end_time:}
|
||||
end
|
||||
end
|
||||
end
|
||||
16
bindings/ruby/test/test_vad_segments.rb
Normal file
16
bindings/ruby/test/test_vad_segments.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
require_relative "helper"
|
||||
|
||||
class TestVADSegments < TestBase
|
||||
def test_initialize
|
||||
segments = Whisper::VAD::Segments.new
|
||||
|
||||
assert_raise do
|
||||
segments.each do |segment|
|
||||
end
|
||||
end
|
||||
|
||||
assert_raise do
|
||||
segments.length
|
||||
end
|
||||
end
|
||||
end
|
||||
350
bindings/ruby/test/test_whisper.rb
Normal file
350
bindings/ruby/test/test_whisper.rb
Normal file
@@ -0,0 +1,350 @@
|
||||
require_relative "helper"
|
||||
require "stringio"
|
||||
require "etc"
|
||||
require "pathname"
|
||||
|
||||
# Exists to detect memory-related bug
|
||||
Whisper.log_set ->(level, buffer, user_data) {}, nil
|
||||
|
||||
class TestWhisper < TestBase
|
||||
def setup
|
||||
@params = Whisper::Params.new
|
||||
end
|
||||
|
||||
def test_whisper
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
params = Whisper::Params.new
|
||||
params.print_timestamps = false
|
||||
|
||||
@whisper.transcribe(AUDIO, params) {|text|
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, text)
|
||||
}
|
||||
end
|
||||
|
||||
def test_whisper_pathname
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
params = Whisper::Params.new
|
||||
|
||||
@whisper.transcribe(Pathname(AUDIO), params) {|text|
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, text)
|
||||
}
|
||||
end
|
||||
|
||||
def test_transcribe_non_parallel
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
params = Whisper::Params.new
|
||||
|
||||
@whisper.transcribe(AUDIO, params, n_processors: 1) {|text|
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, text)
|
||||
}
|
||||
end
|
||||
|
||||
def test_transcribe_n_processors
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
params = Whisper::Params.new
|
||||
|
||||
without_log_callback do
|
||||
@whisper.transcribe(AUDIO, params, n_processors: 4) {|text|
|
||||
assert_match(/what you can do for your country/i, text)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def test_free
|
||||
whisper = Whisper::Context.new("base.en")
|
||||
whisper.free
|
||||
|
||||
assert_raise RuntimeError do
|
||||
whisper.model_type
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def without_log_callback
|
||||
Whisper.log_set nil, nil
|
||||
yield
|
||||
ensure
|
||||
Whisper.log_set ->(level, buffer, user_data) {}, nil
|
||||
end
|
||||
|
||||
sub_test_case "After transcription" do
|
||||
def test_full_n_segments
|
||||
assert_equal 1, whisper.full_n_segments
|
||||
end
|
||||
|
||||
def test_full_lang_id
|
||||
assert_equal 0, whisper.full_lang_id
|
||||
end
|
||||
|
||||
def test_full_get_segment
|
||||
segment = whisper.full_get_segment(0)
|
||||
assert_equal 0, segment.start_time
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, segment.text)
|
||||
end
|
||||
|
||||
def test_full_get_segment_t0
|
||||
assert_equal 0, whisper.full_get_segment_t0(0)
|
||||
assert_raise IndexError do
|
||||
whisper.full_get_segment_t0(whisper.full_n_segments)
|
||||
end
|
||||
assert_raise IndexError do
|
||||
whisper.full_get_segment_t0(-1)
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_get_segment_t1
|
||||
t1 = whisper.full_get_segment_t1(0)
|
||||
assert_kind_of Integer, t1
|
||||
assert t1 > 0
|
||||
assert_raise IndexError do
|
||||
whisper.full_get_segment_t1(whisper.full_n_segments)
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_get_segment_speaker_turn_next
|
||||
assert_false whisper.full_get_segment_speaker_turn_next(0)
|
||||
end
|
||||
|
||||
def test_full_get_segment_text
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, whisper.full_get_segment_text(0))
|
||||
end
|
||||
|
||||
def test_full_get_segment_no_speech_prob
|
||||
prob = whisper.full_get_segment_no_speech_prob(0)
|
||||
assert prob > 0.0
|
||||
assert prob < 1.0
|
||||
end
|
||||
end
|
||||
|
||||
def test_lang_max_id
|
||||
assert_kind_of Integer, Whisper.lang_max_id
|
||||
end
|
||||
|
||||
def test_lang_id
|
||||
assert_equal 0, Whisper.lang_id("en")
|
||||
assert_raise ArgumentError do
|
||||
Whisper.lang_id("non existing language")
|
||||
end
|
||||
end
|
||||
|
||||
def test_lang_str
|
||||
assert_equal "en", Whisper.lang_str(0)
|
||||
assert_raise IndexError do
|
||||
Whisper.lang_str(Whisper.lang_max_id + 1)
|
||||
end
|
||||
end
|
||||
|
||||
def test_lang_str_full
|
||||
assert_equal "english", Whisper.lang_str_full(0)
|
||||
assert_raise IndexError do
|
||||
Whisper.lang_str_full(Whisper.lang_max_id + 1)
|
||||
end
|
||||
end
|
||||
|
||||
def test_system_info_str
|
||||
assert_match(/\AWHISPER : COREML = \d | OPENVINO = \d |/, Whisper.system_info_str)
|
||||
end
|
||||
|
||||
def test_version
|
||||
assert_kind_of String, Whisper::VERSION
|
||||
end
|
||||
|
||||
def test_log_set
|
||||
user_data = Object.new
|
||||
logs = []
|
||||
log_callback = ->(level, buffer, udata) {
|
||||
logs << [level, buffer, udata]
|
||||
}
|
||||
Whisper.log_set log_callback, user_data
|
||||
Whisper::Context.new("base.en")
|
||||
sleep 0.1 # wait for logs dequeued
|
||||
|
||||
assert logs.length > 30
|
||||
logs.each do |log|
|
||||
assert_include [Whisper::LOG_LEVEL_DEBUG, Whisper::LOG_LEVEL_INFO, Whisper::LOG_LEVEL_WARN], log[0]
|
||||
assert_same user_data, log[2]
|
||||
end
|
||||
end
|
||||
|
||||
def test_log_suppress
|
||||
stderr = $stderr
|
||||
Whisper.log_set ->(level, buffer, user_data) {
|
||||
# do nothing
|
||||
}, nil
|
||||
dev = StringIO.new("")
|
||||
$stderr = dev
|
||||
Whisper::Context.new("base.en")
|
||||
assert_empty dev.string
|
||||
ensure
|
||||
$stderr = stderr
|
||||
end
|
||||
|
||||
def test_access_attribute_without_initialization
|
||||
whisper = Whisper::Context.allocate
|
||||
assert_raise do
|
||||
whisper.model_type
|
||||
end
|
||||
end
|
||||
|
||||
sub_test_case "full" do
|
||||
def setup
|
||||
super
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
@samples = File.read(AUDIO, nil, 78).unpack("s<*").collect {|i| i.to_f / 2**15}
|
||||
end
|
||||
|
||||
def test_full
|
||||
@whisper.full(@params, @samples, @samples.length)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, @whisper.each_segment.first.text)
|
||||
end
|
||||
|
||||
def test_full_without_length
|
||||
@whisper.full(@params, @samples)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, @whisper.each_segment.first.text)
|
||||
end
|
||||
|
||||
def test_full_enumerator
|
||||
samples = @samples.each
|
||||
@whisper.full(@params, samples, @samples.length)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, @whisper.each_segment.first.text)
|
||||
end
|
||||
|
||||
def test_full_enumerator_without_length
|
||||
samples = @samples.each
|
||||
assert_raise ArgumentError do
|
||||
@whisper.full(@params, samples)
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_enumerator_with_too_large_length
|
||||
samples = @samples.each.take(10).to_enum
|
||||
assert_raise StopIteration do
|
||||
@whisper.full(@params, samples, 11)
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_with_memory_view
|
||||
samples = JFKReader.new(AUDIO)
|
||||
@whisper.full(@params, samples)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, @whisper.each_segment.first.text)
|
||||
end
|
||||
|
||||
def test_full_with_memroy_view_gc
|
||||
samples = JFKReader.new(AUDIO)
|
||||
@whisper.full(@params, samples)
|
||||
GC.start
|
||||
require "fiddle"
|
||||
Fiddle::MemoryView.export samples do |view|
|
||||
assert_equal 176000, view.to_s.unpack("#{view.format}*").length
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_parallel
|
||||
nprocessors = 2
|
||||
without_log_callback do
|
||||
@whisper.full_parallel(@params, @samples, @samples.length, nprocessors)
|
||||
end
|
||||
|
||||
assert_equal nprocessors, @whisper.full_n_segments
|
||||
text = @whisper.each_segment.collect(&:text).join
|
||||
assert_match(/ask what you can do/i, text)
|
||||
assert_match(/for your country/i, text)
|
||||
end
|
||||
|
||||
def test_full_parallel_with_memory_view
|
||||
nprocessors = 2
|
||||
samples = JFKReader.new(AUDIO)
|
||||
without_log_callback do
|
||||
@whisper.full_parallel(@params, samples, nil, nprocessors)
|
||||
end
|
||||
|
||||
assert_equal nprocessors, @whisper.full_n_segments
|
||||
text = @whisper.each_segment.collect(&:text).join
|
||||
assert_match(/ask what you can do/i, text)
|
||||
assert_match(/for your country/i, text)
|
||||
end
|
||||
|
||||
def test_full_parallel_without_length_and_n_processors
|
||||
@whisper.full_parallel(@params, @samples)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
text = @whisper.each_segment.collect(&:text).join
|
||||
assert_match(/ask what you can do/i, text)
|
||||
assert_match(/for your country/i, text)
|
||||
end
|
||||
|
||||
def test_full_parallel_without_length
|
||||
nprocessors = 2
|
||||
without_log_callback do
|
||||
@whisper.full_parallel(@params, @samples, nil, nprocessors)
|
||||
end
|
||||
|
||||
assert_equal nprocessors, @whisper.full_n_segments
|
||||
text = @whisper.each_segment.collect(&:text).join
|
||||
assert_match(/ask what you can do/i, text)
|
||||
assert_match(/for your country/i, text)
|
||||
end
|
||||
|
||||
def test_full_parallel_without_n_processors
|
||||
@whisper.full_parallel(@params, @samples, @samples.length)
|
||||
|
||||
assert_equal 1, @whisper.full_n_segments
|
||||
text = @whisper.each_segment.collect(&:text).join
|
||||
assert_match(/ask what you can do/i, text)
|
||||
assert_match(/for your country/i, text)
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_srt
|
||||
whisper = Whisper::Context.new("base.en")
|
||||
whisper.transcribe AUDIO, @params
|
||||
|
||||
lines = whisper.to_srt.lines
|
||||
assert_match(/\A\d+\n/, lines[0])
|
||||
assert_match(/\d{2}:\d{2}:\d{2},\d{3} --> \d{2}:\d{2}:\d{2},\d{3}\n/, lines[1])
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, lines[2])
|
||||
end
|
||||
|
||||
def test_to_webvtt
|
||||
whisper = Whisper::Context.new("base.en")
|
||||
whisper.transcribe AUDIO, @params
|
||||
|
||||
lines = whisper.to_webvtt.lines
|
||||
assert_equal "WEBVTT\n", lines[0]
|
||||
assert_equal "\n", lines[1]
|
||||
assert_match(/\A\d+\n/, lines[2])
|
||||
assert_match(/\d{2}:\d{2}:\d{2}\.\d{3} --> \d{2}:\d{2}:\d{2}\.\d{3}\n/, lines[3])
|
||||
assert_match(/ask not what your country can do for you, ask what you can do for your country/, lines[4])
|
||||
end
|
||||
|
||||
sub_test_case "Format needs escape" do
|
||||
def setup
|
||||
@whisper = Whisper::Context.new("base.en")
|
||||
@whisper.transcribe AUDIO, Whisper::Params.new
|
||||
segment = @whisper.each_segment.first
|
||||
segment.define_singleton_method :text do
|
||||
"& so my fellow Americans --> ask not what your country can do for you <-- ask what you can do for your country."
|
||||
end
|
||||
@whisper.define_singleton_method :each_segment do
|
||||
Enumerator.new(3) {|yielder| 3.times {yielder << segment}}
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_srt_escape
|
||||
assert_equal "& so my fellow Americans --> ask not what your country can do for you <-- ask what you can do for your country.\n", @whisper.to_srt.lines[2]
|
||||
end
|
||||
|
||||
def test_to_webvtt_escape
|
||||
assert_equal "& so my fellow Americans --> ask not what your country can do for you <-- ask what you can do for your country.\n", @whisper.to_webvtt.lines[4]
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user