diff --git a/LLama/Exceptions/RuntimeError.cs b/LLama/Exceptions/RuntimeError.cs index a8ea0531..c56d78ff 100644 --- a/LLama/Exceptions/RuntimeError.cs +++ b/LLama/Exceptions/RuntimeError.cs @@ -17,4 +17,23 @@ public class RuntimeError { } +} + +/// +/// Loading model weights failed +/// +public class LoadWeightsFailedException + : RuntimeError +{ + /// + /// The model path which failed to load + /// + public string ModelPath { get; } + + /// + public LoadWeightsFailedException(string modelPath) + : base($"Failed to load model '{modelPath}'") + { + ModelPath = modelPath; + } } \ No newline at end of file diff --git a/LLama/Native/SafeLlamaModelHandle.cs b/LLama/Native/SafeLlamaModelHandle.cs index 8ffa2be3..5724ec7e 100644 --- a/LLama/Native/SafeLlamaModelHandle.cs +++ b/LLama/Native/SafeLlamaModelHandle.cs @@ -2,6 +2,7 @@ using System.Buffers; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Runtime.InteropServices; using System.Text; using LLama.Exceptions; @@ -63,11 +64,16 @@ namespace LLama.Native /// public static SafeLlamaModelHandle LoadFromFile(string modelPath, LLamaModelParams lparams) { - var model = llama_load_model_from_file(modelPath, lparams); - if (model == null) - throw new RuntimeError($"Failed to load model {modelPath}."); - - return model; + // Try to open the model file, this will check: + // - File exists (automatically throws FileNotFoundException) + // - File is readable (explicit check) + // This provides better error messages that llama.cpp, which would throw an access violation exception in both cases. + using (var fs = new FileStream(modelPath, FileMode.Open)) + if (!fs.CanRead) + throw new InvalidOperationException($"Model file '{modelPath}' is not readable"); + + return llama_load_model_from_file(modelPath, lparams) + ?? throw new LoadWeightsFailedException($"Failed to load model {modelPath}."); } #region native API