bark.cpp
bark.cpp copied to clipboard
DivideByZeroException in bark_load_model when calling ggml_time_us()
When calling bark_load_model
from the C# BarkSharp wrapper, a System.DivideByZeroException
is thrown at the line int64_t t_load_start_us = ggml_time_us();
. This seems to indicate that the ggml_time_us()
function is attempting to divide by zero, likely because the timer_freq
variable has not been properly initialized.
Inserting a call to ggml_time_init()
at the beginning of bark_load_model
to initialize the timer leads to a StackOverflowException
during the allocation of memory with ggml_allocr_new_from_buffer
. This suggests a potential issue with memory management or initialization within the GGML library.
Reproduction Steps:
- Build the Bark library: Ensure that the Bark library (including GGML) is built successfully.
- Create a C# project: Create a C# project that uses the BarkSharp wrapper to interact with the Bark library.
-
Load the Bark model: Attempt to load the Bark model using the
BarkContext
class constructor, providing the path to the model file.
Example Code (Relevant C# snippets):
// BarkContext.cs
public BarkContext(string modelPath, BarkContextParams parameters, uint seed)
{
var modelPathPtr = Marshal.StringToHGlobalAnsi(modelPath);
_context = LoadModel(modelPathPtr , parameters, seed); // This call eventually leads to the exception
// ...
}
// NativeMethods.cs
[DllImport(NativeLibraryManager.LibraryName, EntryPoint = "bark_load_model", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadModel(IntPtr modelPath, BarkContextParams parameters, uint seed);
Relevant C++ Code (bark.cpp):
struct bark_context* bark_load_model(const char* model_path, struct bark_context_params params, uint32_t seed) {
int64_t t_load_start_us = ggml_time_us(); // Exception occurs here
struct bark_context* bctx = new bark_context();
bctx->text_model = bark_model();
std::string model_path_str(model_path);
if (!bark_load_model_from_file(model_path_str, bctx, params.verbosity)) {
fprintf(stderr, "%s: failed to load model weights from '%s'\n", __func__, model_path);
return nullptr;
}
bctx->rng = std::mt19937(seed);
bctx->params = params;
bctx->stats.t_load_us = ggml_time_us() - t_load_start_us;
return bctx;
}
Relevant C++ Code (ggml.c):
int64_t ggml_time_us(void) {
LARGE_INTEGER t;
QueryPerformanceCounter(&t);
return ((t.QuadPart - timer_start) * 1000000) / timer_freq; // Potential division by zero
}
void ggml_time_init(void) {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
timer_freq = frequency.QuadPart;
QueryPerformanceCounter(&timer_start);
}
Expected Behavior:
The bark_load_model
function should load the model successfully without throwing any exceptions. The ggml_time_us()
function should return a valid timestamp.
Actual Behavior:
A System.DivideByZeroException
is thrown when calling ggml_time_us()
. Attempting to fix this by calling ggml_time_init()
at the beginning of bark_load_model
results in a StackOverflowException
during memory allocation.
Possible Causes:
-
Missing timer initialization: The
timer_freq
variable inggml_time_us()
might not be initialized properly before it is used, leading to the division by zero error. -
Circular dependency or recursive call: The
StackOverflowException
when callingggml_time_init()
might indicate a circular dependency or a recursive function call that exceeds the stack limit. - Memory allocation issues: There might be problems with memory allocation or initialization within GGML, leading to the stack overflow during the creation of the allocator.