static_embeddings 0.1.1 → 0.1.2

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.
@@ -70,6 +70,8 @@ module StaticEmbeddings
70
70
  76 => :clean_text
71
71
  }.freeze
72
72
 
73
+ VERIFY_CHUNK_BYTES = 1024 * 1024
74
+
73
75
  module_function
74
76
 
75
77
  def hash_bytes(str, seed = HASH_SEED)
@@ -120,14 +122,28 @@ module StaticEmbeddings
120
122
  end
121
123
 
122
124
  def verify(path)
123
- data = File.binread(path)
124
- raise InvalidModelError, "file too small" if data.bytesize < HEADER_SIZE
125
- raise InvalidModelError, "bad magic" unless data.byteslice(0, 8) == MAGIC.b
125
+ raise InvalidModelError, "file too small" if File.size(path) < HEADER_SIZE
126
+
127
+ File.open(path, "rb") do |io|
128
+ header = io.read(HEADER_SIZE)
129
+ raise InvalidModelError, "bad magic" unless header.byteslice(0, 8) == MAGIC.b
126
130
 
127
- stored = data.byteslice(CHECKSUM_OFFSET, CHECKSUM_SIZE)
128
- actual = checksum_for_verify(data)
131
+ stored = header.byteslice(CHECKSUM_OFFSET, CHECKSUM_SIZE)
132
+ actual = streaming_checksum(io, header)
129
133
 
130
- { ok: stored == actual, expected: actual.unpack1("H*"), stored: stored.unpack1("H*") }
134
+ { ok: stored == actual, expected: actual.unpack1("H*"), stored: stored.unpack1("H*") }
135
+ end
136
+ end
137
+
138
+ def streaming_checksum(io, header)
139
+ digest = Digest::SHA256.new
140
+ zeroed = header.dup
141
+ zeroed[CHECKSUM_OFFSET, CHECKSUM_SIZE] = "\0".b * CHECKSUM_SIZE
142
+ digest << zeroed
143
+
144
+ buffer = String.new(capacity: VERIFY_CHUNK_BYTES)
145
+ digest << buffer while io.read(VERIFY_CHUNK_BYTES, buffer)
146
+ digest.digest
131
147
  end
132
148
 
133
149
  def binary_string(capacity = nil)
@@ -280,10 +296,5 @@ module StaticEmbeddings
280
296
  buffer[offset, 8] = [value & 0xFFFFFFFF, value >> 32].pack("V2")
281
297
  end
282
298
 
283
- def checksum_for_verify(data)
284
- zeroed = data.dup
285
- zeroed[CHECKSUM_OFFSET, CHECKSUM_SIZE] = "\0".b * CHECKSUM_SIZE
286
- Digest::SHA256.digest(zeroed)
287
- end
288
299
  end
289
300
  end
@@ -1,3 +1,3 @@
1
1
  module StaticEmbeddings
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/tools/benchmark.rb CHANGED
@@ -12,8 +12,11 @@ CORPUS = (1..5_000).map do |i|
12
12
  "локальный поиск по тексту номер #{i} hello world static embedding vector search"
13
13
  end
14
14
 
15
- tokens = CORPUS.sum { |t| model.tokenize(t).length }
16
- bytes = CORPUS.sum(&:bytesize)
15
+ stats = CORPUS.map { |t| model.embed_with_stats(t) }
16
+ tokens = stats.sum { |s| s[:token_count] }
17
+ truncated = stats.count { |s| s[:truncated] }
18
+ logical_bytes = CORPUS.sum(&:bytesize)
19
+ processed_bytes = truncated.zero? ? logical_bytes : nil
17
20
 
18
21
  def timed(label, iterations)
19
22
  elapsed = Benchmark.realtime { iterations.times { yield } }
@@ -28,11 +31,17 @@ per_token_ns = (batch1 / tokens) * 1e9
28
31
  per_token_per_100dim = per_token_ns / (model.dim / 100.0)
29
32
 
30
33
  puts "model #{model.model_id} dim=#{model.dim} vocab=#{model.vocab_size}"
31
- puts "corpus #{CORPUS.length} texts, #{tokens} tokens, #{bytes} bytes"
34
+ puts "corpus #{CORPUS.length} texts, #{tokens} tokens, #{logical_bytes} logical bytes"
35
+ puts "truncation #{truncated} of #{CORPUS.length} texts truncated at max_tokens=#{model.max_tokens}"
32
36
  puts
33
37
  puts "single embed #{((single / 2_000) * 1e6).round(1)} us/call"
34
38
  puts "batch #{(CORPUS.length / batch1).round} texts/s, #{(tokens / batch1).round} tokens/s"
35
- puts "tokenize only #{((tok_only / bytes) * 1e9).round(1)} ns/input byte"
39
+ if processed_bytes
40
+ puts "tokenize only #{((tok_only / processed_bytes) * 1e9).round(1)} ns/processed byte"
41
+ else
42
+ puts "tokenize only #{(tok_only * 1e3).round(1)} ms total (no ns/byte: truncation makes"
43
+ puts " processed bytes smaller than the #{logical_bytes} logical bytes)"
44
+ end
36
45
  puts
37
46
  puts "normalised #{per_token_ns.round(1)} ns/token"
38
47
  puts " #{per_token_per_100dim.round(1)} ns/token/100dim"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: static_embeddings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Haydarov
@@ -85,10 +85,13 @@ files:
85
85
  - docs/PERFORMANCE.md
86
86
  - exe/static_embeddings
87
87
  - ext/static_embeddings/extconf.rb
88
+ - ext/static_embeddings/se_alloc_stats.c
88
89
  - ext/static_embeddings/se_embed.c
90
+ - ext/static_embeddings/se_f16.c
89
91
  - ext/static_embeddings/se_format.c
90
92
  - ext/static_embeddings/se_internal.h
91
93
  - ext/static_embeddings/se_tokenizer.c
94
+ - ext/static_embeddings/se_topk.c
92
95
  - ext/static_embeddings/se_unicode.c
93
96
  - ext/static_embeddings/static_embeddings.c
94
97
  - lib/static_embeddings.rb