red-candle 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a3ac57ccd28cb2eb647c5a71f42fdbdf84a9dcaabd906165daca3d57c4a8eb0
4
- data.tar.gz: 283104e93802ac97f11525226c9e41dc3bebccb8706d5b69a6a648d62cf2ccad
3
+ metadata.gz: 56022d9cb3677fa07bedae0272b5855374e2a6a5af863e055b546e1a0a9ddd5d
4
+ data.tar.gz: b027603292ba34d1cf75460e74edf1d2472ea5651f8690d86adc50dc7000bdcc
5
5
  SHA512:
6
- metadata.gz: d5be5ca76fe5441ee1fd87ea83bcd02f5a630c3410a4dccc347da28290ef408c4c2cae428134f2a8fba839fe5aacf2b7593fe45274c967600e6684d09f212a01
7
- data.tar.gz: 72289aaf0c17dea679acfa4f92be5371f2543293e27dab0752b39c77a1c2be98c480c0ce7266bc07519551770abdf53fdbbf0f4d3c1fdf6ba928c2452e598060
6
+ metadata.gz: cbc00f433b91bddc9d117e836488f1991d42a4e7ca8c9968949adfe671277a22e36a2a65f26b7cd17036c24c6e24d6a45ce1f4684f6281811d5b25f5830b0558
7
+ data.tar.gz: 2970cd8e5d7d59c6d6be5e69219da7c518962e12b59f2c18f2d4fa806a50d264198b1c027f82263e185987e2f75d0fd4ee81194ed272a257fdd804575756b82c
data/Cargo.lock CHANGED
@@ -300,9 +300,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
300
300
 
301
301
  [[package]]
302
302
  name = "bytes"
303
- version = "1.10.1"
303
+ version = "1.11.1"
304
304
  source = "registry+https://github.com/rust-lang/crates.io-index"
305
- checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
305
+ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
306
306
 
307
307
  [[package]]
308
308
  name = "candle"
@@ -819,7 +819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
819
819
  checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
820
820
  dependencies = [
821
821
  "libc",
822
- "windows-sys 0.61.0",
822
+ "windows-sys 0.59.0",
823
823
  ]
824
824
 
825
825
  [[package]]
@@ -2468,9 +2468,9 @@ dependencies = [
2468
2468
 
2469
2469
  [[package]]
2470
2470
  name = "quinn-proto"
2471
- version = "0.11.13"
2471
+ version = "0.11.14"
2472
2472
  source = "registry+https://github.com/rust-lang/crates.io-index"
2473
- checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
2473
+ checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
2474
2474
  dependencies = [
2475
2475
  "bytes",
2476
2476
  "getrandom 0.3.3",
@@ -2498,7 +2498,7 @@ dependencies = [
2498
2498
  "once_cell",
2499
2499
  "socket2",
2500
2500
  "tracing",
2501
- "windows-sys 0.60.2",
2501
+ "windows-sys 0.59.0",
2502
2502
  ]
2503
2503
 
2504
2504
  [[package]]
@@ -2819,7 +2819,7 @@ dependencies = [
2819
2819
  "errno",
2820
2820
  "libc",
2821
2821
  "linux-raw-sys",
2822
- "windows-sys 0.61.0",
2822
+ "windows-sys 0.59.0",
2823
2823
  ]
2824
2824
 
2825
2825
  [[package]]
@@ -2850,9 +2850,9 @@ dependencies = [
2850
2850
 
2851
2851
  [[package]]
2852
2852
  name = "rustls-webpki"
2853
- version = "0.103.5"
2853
+ version = "0.103.10"
2854
2854
  source = "registry+https://github.com/rust-lang/crates.io-index"
2855
- checksum = "b5a37813727b78798e53c2bec3f5e8fe12a6d6f8389bf9ca7802add4c9905ad8"
2855
+ checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
2856
2856
  dependencies = [
2857
2857
  "aws-lc-rs",
2858
2858
  "ring",
@@ -3195,9 +3195,9 @@ dependencies = [
3195
3195
 
3196
3196
  [[package]]
3197
3197
  name = "tar"
3198
- version = "0.4.44"
3198
+ version = "0.4.45"
3199
3199
  source = "registry+https://github.com/rust-lang/crates.io-index"
3200
- checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
3200
+ checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973"
3201
3201
  dependencies = [
3202
3202
  "filetime",
3203
3203
  "libc",
@@ -3214,7 +3214,7 @@ dependencies = [
3214
3214
  "getrandom 0.3.3",
3215
3215
  "once_cell",
3216
3216
  "rustix",
3217
- "windows-sys 0.61.0",
3217
+ "windows-sys 0.59.0",
3218
3218
  ]
3219
3219
 
3220
3220
  [[package]]
@@ -3888,7 +3888,7 @@ version = "0.1.11"
3888
3888
  source = "registry+https://github.com/rust-lang/crates.io-index"
3889
3889
  checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
3890
3890
  dependencies = [
3891
- "windows-sys 0.61.0",
3891
+ "windows-sys 0.48.0",
3892
3892
  ]
3893
3893
 
3894
3894
  [[package]]
@@ -1,6 +1,7 @@
1
1
  use magnus::{function, prelude::*, Ruby};
2
2
 
3
3
  use crate::ruby::candle_utils;
4
+ use crate::ruby::utils::ensure_hf_cache_dir;
4
5
  use crate::ruby::Result;
5
6
 
6
7
  pub mod llm;
@@ -22,19 +23,20 @@ const DEFAULT_DEVICE: &str = "cpu";
22
23
  pub fn get_build_info() -> magnus::RHash {
23
24
  let ruby = magnus::Ruby::get().unwrap();
24
25
  let hash = ruby.hash_new();
25
-
26
+
26
27
  let _ = hash.aset("default_device", DEFAULT_DEVICE);
27
28
  let _ = hash.aset("cuda_available", cfg!(feature = "cuda"));
28
29
  let _ = hash.aset("metal_available", cfg!(feature = "metal"));
29
30
  let _ = hash.aset("mkl_available", cfg!(feature = "mkl"));
30
31
  let _ = hash.aset("accelerate_available", cfg!(feature = "accelerate"));
31
32
  let _ = hash.aset("cudnn_available", cfg!(feature = "cudnn"));
32
-
33
+
33
34
  hash
34
35
  }
35
36
 
36
37
  #[magnus::init]
37
38
  fn init(ruby: &Ruby) -> Result<()> {
39
+ ensure_hf_cache_dir();
38
40
  let rb_candle = ruby.define_module("Candle")?;
39
41
 
40
42
  // Export build info
@@ -34,7 +34,7 @@ impl Gemma {
34
34
  pub async fn from_pretrained_with_tokenizer(model_id: &str, device: Device, tokenizer_source: Option<&str>) -> CandleResult<Self> {
35
35
  let api = Api::new()
36
36
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
37
-
37
+
38
38
  let repo = api.repo(Repo::model(model_id.to_string()));
39
39
 
40
40
  // Download model files
@@ -41,7 +41,7 @@ impl Llama {
41
41
  pub async fn from_pretrained_with_tokenizer(model_id: &str, device: Device, tokenizer_source: Option<&str>) -> CandleResult<Self> {
42
42
  let api = Api::new()
43
43
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
44
-
44
+
45
45
  let repo = api.repo(Repo::model(model_id.to_string()));
46
46
 
47
47
  // Download model files
@@ -34,7 +34,7 @@ impl Mistral {
34
34
  pub async fn from_pretrained_with_tokenizer(model_id: &str, device: Device, tokenizer_source: Option<&str>) -> CandleResult<Self> {
35
35
  let api = Api::new()
36
36
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
37
-
37
+
38
38
  let repo = api.repo(Repo::model(model_id.to_string()));
39
39
 
40
40
  // Download model files
@@ -42,7 +42,7 @@ impl Phi {
42
42
  pub async fn from_pretrained_with_tokenizer(model_id: &str, device: Device, tokenizer_source: Option<&str>) -> CandleResult<Self> {
43
43
  let api = Api::new()
44
44
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
45
-
45
+
46
46
  let repo = api.model(model_id.to_string());
47
47
 
48
48
  // Download configuration
@@ -53,7 +53,7 @@ impl QuantizedGGUF {
53
53
 
54
54
  let api = Api::new()
55
55
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
56
-
56
+
57
57
  let repo = api.model(actual_model_id.to_string());
58
58
 
59
59
  // Download GGUF file
@@ -34,7 +34,7 @@ impl Qwen {
34
34
  pub async fn from_pretrained_with_tokenizer(model_id: &str, device: Device, tokenizer_source: Option<&str>) -> CandleResult<Self> {
35
35
  let api = Api::new()
36
36
  .map_err(|e| candle_core::Error::Msg(format!("Failed to create HF API: {}", e)))?;
37
-
37
+
38
38
  let repo = api.model(model_id.to_string());
39
39
 
40
40
  // Download configuration
@@ -4,6 +4,32 @@ use ::candle_core::Tensor as CoreTensor;
4
4
 
5
5
  use crate::ruby::Result;
6
6
 
7
+ /// Ensures the HuggingFace cache directory exists before Api::new() is called.
8
+ ///
9
+ /// The hf_hub crate stores downloaded models in a "hub" subdirectory under the
10
+ /// cache root. When the parent directory doesn't exist, hf_hub may fail to
11
+ /// create the full path or silently produce an empty cache. This function
12
+ /// pre-creates the directory tree to avoid the race condition described in
13
+ /// issue #72.
14
+ ///
15
+ /// Resolution order for the cache root:
16
+ /// 1. $HF_HOME (if set)
17
+ /// 2. $XDG_CACHE_HOME/huggingface (if XDG_CACHE_HOME is set)
18
+ /// 3. ~/.cache/huggingface
19
+ pub fn ensure_hf_cache_dir() {
20
+ let cache_root = if let Ok(hf_home) = std::env::var("HF_HOME") {
21
+ std::path::PathBuf::from(hf_home)
22
+ } else if let Ok(xdg) = std::env::var("XDG_CACHE_HOME") {
23
+ std::path::PathBuf::from(xdg).join("huggingface")
24
+ } else if let Ok(home) = std::env::var("HOME") {
25
+ std::path::PathBuf::from(home).join(".cache").join("huggingface")
26
+ } else {
27
+ return;
28
+ };
29
+ let hub_dir = cache_root.join("hub");
30
+ let _ = std::fs::create_dir_all(hub_dir);
31
+ }
32
+
7
33
  pub fn actual_index(t: &CoreTensor, dim: usize, index: i64) -> candle_core::Result<usize> {
8
34
  let dim = t.dim(dim)?;
9
35
  if 0 <= index {
@@ -1,5 +1,5 @@
1
1
  # :nocov:
2
2
  module Candle
3
- VERSION = "1.4.0"
3
+ VERSION = "1.4.1"
4
4
  end
5
5
  # :nocov:
data/lib/candle.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require_relative "candle/logger"
2
- require_relative "candle/candle"
2
+ require "candle/candle"
3
3
  require_relative "candle/tensor"
4
4
  require_relative "candle/device_utils"
5
5
  require_relative "candle/embedding_model_type"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: red-candle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Petersen
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: '3.13'
181
+ - !ruby/object:Gem::Dependency
182
+ name: irb
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
181
195
  description: Ruby gem for running state-of-the-art language models locally. Access
182
196
  LLMs, embeddings, rerankers, and NER models directly from Ruby using Rust-powered
183
197
  Candle with Metal/CUDA acceleration.
@@ -267,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
281
  version: '3.3'
268
282
  requirements:
269
283
  - Rust >= 1.85
270
- rubygems_version: 4.0.3
284
+ rubygems_version: 4.0.6
271
285
  specification_version: 4
272
286
  summary: Ruby gem for running state-of-the-art language models locally. Access LLMs,
273
287
  embeddings, rerankers, and NER models directly from Ruby using Rust-powered Candle