fastembed 1.0.0 → 1.1.0

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.
data/plan.md ADDED
@@ -0,0 +1,257 @@
1
+ # FastEmbed-rb Roadmap
2
+
3
+ This document outlines features from the original [FastEmbed Python library](https://github.com/qdrant/fastembed) that are not yet implemented in fastembed-rb.
4
+
5
+ ## Current Status (v1.0.0)
6
+
7
+ ### Implemented
8
+ - Dense text embeddings with 12 models
9
+ - Automatic model downloading from HuggingFace
10
+ - Lazy evaluation via `Enumerator`
11
+ - Query/passage prefixes for retrieval models
12
+ - Mean pooling and L2 normalization
13
+ - Configurable batch size and threading
14
+ - CoreML execution provider support
15
+ - CLI tool (`fastembed`)
16
+ - **Reranking / Cross-Encoder models** (5 models)
17
+
18
+ ## Feature Gap Analysis
19
+
20
+ ### High Priority
21
+
22
+ #### 1. Sparse Text Embeddings
23
+ The Python library supports sparse embedding models that return indices and values rather than dense vectors. These are useful for hybrid search combining keyword and semantic matching.
24
+
25
+ **Models to support:**
26
+ - `Qdrant/bm25` - Classic BM25 (0.010 GB)
27
+ - `Qdrant/bm42-all-minilm-l6-v2-attentions` - Attention-based sparse (0.090 GB)
28
+ - `prithivida/Splade_PP_en_v1` - SPLADE++ (0.532 GB)
29
+
30
+ **API design:**
31
+ ```ruby
32
+ sparse = Fastembed::SparseTextEmbedding.new
33
+ result = sparse.embed(["hello world"]).first
34
+ # => { indices: [123, 456, 789], values: [0.5, 0.3, 0.2] }
35
+ ```
36
+
37
+ **Implementation notes:**
38
+ - Need new `SparseTextEmbedding` class
39
+ - Different output format (sparse vectors instead of dense)
40
+ - May require different tokenization approach for BM25
41
+
42
+ #### 2. Late Interaction (ColBERT) Models
43
+ ColBERT-style models produce token-level embeddings rather than a single vector per document. This enables more fine-grained matching.
44
+
45
+ **Models to support:**
46
+ - `answerdotai/answerai-colbert-small-v1` (96 dim)
47
+ - `colbert-ir/colbertv2.0` (128 dim)
48
+ - `jinaai/jina-colbert-v2` (128 dim)
49
+
50
+ **API design:**
51
+ ```ruby
52
+ colbert = Fastembed::LateInteractionTextEmbedding.new
53
+ result = colbert.embed(["hello world"]).first
54
+ # => Array of token embeddings, shape: [num_tokens, dim]
55
+ ```
56
+
57
+ **Implementation notes:**
58
+ - Returns 2D array per document (tokens × dimensions)
59
+ - Different pooling strategy (no pooling, keep all tokens)
60
+ - Scoring requires MaxSim operation between query and document tokens
61
+
62
+ #### ~~3. Reranking / Cross-Encoder Models~~ ✅ IMPLEMENTED
63
+
64
+ See `Fastembed::TextCrossEncoder` class.
65
+
66
+ ### Medium Priority
67
+
68
+ #### ~~4. Image Embeddings~~ ✅ IMPLEMENTED
69
+
70
+ Vision models for converting images to vectors. Requires `mini_magick` gem.
71
+
72
+ **Supported models:**
73
+ - `Qdrant/resnet50-onnx` (2048 dim)
74
+ - `Qdrant/clip-ViT-B-32-vision` (512 dim)
75
+ - `jinaai/jina-clip-v1` (768 dim)
76
+
77
+ **Usage:**
78
+ ```ruby
79
+ # Add to Gemfile: gem "mini_magick"
80
+ image_embed = Fastembed::ImageEmbedding.new
81
+ vector = image_embed.embed(["path/to/image.jpg"]).first
82
+ ```
83
+
84
+ #### ~~5. Custom Model Support~~ ✅ IMPLEMENTED
85
+
86
+ Implemented via `CustomModelRegistry` module. Users can register custom models:
87
+
88
+ ```ruby
89
+ Fastembed.register_model(
90
+ model_name: "my-org/my-model",
91
+ dim: 768,
92
+ sources: { hf: "my-org/my-model" }
93
+ )
94
+
95
+ embed = Fastembed::TextEmbedding.new(model_name: "my-org/my-model")
96
+ ```
97
+
98
+ Also supports local model loading via `local_model_dir` parameter.
99
+
100
+ ### Low Priority
101
+
102
+ #### 6. Multimodal Late Interaction (ColPali)
103
+ ColPali models that can embed both images and text for document retrieval.
104
+
105
+ **Models to support:**
106
+ - `vidore/colpali-v1.2`
107
+ - `vidore/colqwen2-v1.0`
108
+
109
+ **Implementation notes:**
110
+ - Combines image and text embedding
111
+ - Requires vision preprocessing
112
+ - Complex architecture, lower priority
113
+
114
+ #### 7. Quantized Models
115
+ Support for INT8/INT4 quantized models for faster inference and lower memory usage.
116
+
117
+ **Implementation notes:**
118
+ - ONNX Runtime supports quantized models natively
119
+ - Need to add quantized model variants to registry
120
+ - Trade-off between speed and accuracy
121
+
122
+ ## ~~CLI Enhancements~~ ✅ IMPLEMENTED
123
+
124
+ All planned CLI features have been implemented:
125
+
126
+ - ✅ `fastembed download <model>` - Pre-download models for offline use
127
+ - ✅ `fastembed benchmark` - Run performance benchmarks with configurable iterations
128
+ - ✅ `fastembed info <model>` - Show detailed model information including cache status
129
+ - ✅ `-i input.txt` - Read texts from file (one per line)
130
+ - ✅ `-p` / `--progress` - Show progress bar during embedding
131
+ - ✅ `-q` / `--quiet` - Suppress progress output for scripting
132
+
133
+ ## Breaking Changes for v2.0
134
+
135
+ If we do a major version bump:
136
+
137
+ 1. Consider making `embed()` return an Array instead of Enumerator by default
138
+ 2. Rename `query_embed`/`passage_embed` to `embed_query`/`embed_passage` for consistency
139
+ 3. Use keyword arguments consistently throughout
140
+
141
+ ---
142
+
143
+ ## Refactoring Plan
144
+
145
+ ### Completed: Phase 1 - Extract Shared Helpers
146
+
147
+ - [x] Create `Validators` module for document validation
148
+ - [x] Extract `prepare_model_inputs` to BaseModel
149
+ - [x] Extract `setup_model_and_tokenizer` to BaseModel
150
+ - [x] Update all model classes to use shared helpers
151
+
152
+ **Result:** Reduced ~60 lines of duplicated code across 4 model classes.
153
+
154
+ ---
155
+
156
+ ### Completed: Phase 2 - Add Missing Features (Medium Risk)
157
+
158
+ Goal: Achieve API consistency across all model types.
159
+
160
+ #### 2.1 Add `passage_embed` to TextSparseEmbedding ✅ IMPLEMENTED
161
+
162
+ Added to TextSparseEmbedding.
163
+
164
+ ```ruby
165
+ # lib/fastembed/sparse_embedding.rb
166
+ def passage_embed(passages, batch_size: 32)
167
+ passages = [passages] if passages.is_a?(String)
168
+ embed(passages, batch_size: batch_size)
169
+ end
170
+ ```
171
+
172
+ #### 2.2 Add async methods to all embedding classes ✅ IMPLEMENTED
173
+
174
+ Added async methods to all model classes:
175
+ - TextSparseEmbedding: embed_async, query_embed_async, passage_embed_async
176
+ - LateInteractionTextEmbedding: embed_async, query_embed_async, passage_embed_async
177
+ - TextCrossEncoder: rerank_async, rerank_with_scores_async
178
+
179
+ ```ruby
180
+ # Add to TextSparseEmbedding
181
+ def embed_async(documents, batch_size: 32)
182
+ Async::Future.new { embed(documents, batch_size: batch_size).to_a }
183
+ end
184
+
185
+ def query_embed_async(queries, batch_size: 32)
186
+ Async::Future.new { query_embed(queries, batch_size: batch_size).to_a }
187
+ end
188
+
189
+ def passage_embed_async(passages, batch_size: 32)
190
+ Async::Future.new { passage_embed(passages, batch_size: batch_size).to_a }
191
+ end
192
+
193
+ # Add to TextCrossEncoder
194
+ def rerank_async(query:, documents:, batch_size: 64)
195
+ Async::Future.new { rerank(query: query, documents: documents, batch_size: batch_size) }
196
+ end
197
+ ```
198
+
199
+ #### 2.3 Add progress callback support to all embedding classes ✅ IMPLEMENTED
200
+
201
+ Added progress callback support to TextSparseEmbedding and LateInteractionTextEmbedding.
202
+
203
+ #### 2.4 Add `show_progress` parameter to TextCrossEncoder ✅ IMPLEMENTED
204
+
205
+ Made configurable (was hardcoded to true).
206
+
207
+ ---
208
+
209
+ ### Completed: Phase 3 - Unify Initialization (Higher Risk)
210
+
211
+ Goal: Consistent initialization API across all model types.
212
+
213
+ #### 3.1 Add quantization support to all models ✅ IMPLEMENTED
214
+
215
+ Added quantization parameter to all model classes (TextSparseEmbedding, LateInteractionTextEmbedding, TextCrossEncoder).
216
+
217
+ #### 3.2 Add local_model_dir support to all models ✅ IMPLEMENTED
218
+
219
+ Added local_model_dir, model_file, and tokenizer_file parameters to all model classes. Shared logic extracted to BaseModel (initialize_from_local, create_local_model_info).
220
+
221
+ #### 3.3 Document batch size rationale ✅ DOCUMENTED
222
+
223
+ Default batch sizes vary by model type based on memory requirements:
224
+
225
+ | Model Type | Default Batch Size | Rationale |
226
+ |------------|-------------------|-----------|
227
+ | TextEmbedding | 256 | Dense embeddings have fixed output size (e.g., 384 floats). Memory is predictable and efficient. |
228
+ | TextSparseEmbedding | 32 | SPLADE models output logits for entire vocabulary (~30k tokens) per sequence position. Much higher memory per document. |
229
+ | LateInteractionTextEmbedding | 32 | ColBERT keeps per-token embeddings (not pooled), so output size scales with sequence length × embedding dim. |
230
+ | TextCrossEncoder | 64 | Processes query-document pairs together. Each pair requires more memory than single documents, but less than sparse/late interaction. |
231
+
232
+ Users can override these defaults via the `batch_size` parameter if they have different memory constraints.
233
+
234
+ ---
235
+
236
+ ### Implementation Priority
237
+
238
+ | Task | Risk | Effort | Value |
239
+ |------|------|--------|-------|
240
+ | 2.1 Add passage_embed to Sparse | Low | Small | Medium |
241
+ | 2.2 Add async to all classes | Low | Medium | High |
242
+ | 2.3 Add progress to all classes | Medium | Medium | Medium |
243
+ | 2.4 Add show_progress to CrossEncoder | Low | Small | Low |
244
+ | 3.1 Add quantization to all | Medium | Medium | Medium |
245
+ | 3.2 Add local_model_dir to all | Medium | Large | Medium |
246
+ | 3.3 Document batch size rationale | Low | Small | Low |
247
+
248
+ ---
249
+
250
+ ## Contributing
251
+
252
+ Contributions are welcome! If you'd like to implement any of these features:
253
+
254
+ 1. Open an issue to discuss the approach
255
+ 2. Follow the existing code style (run `bundle exec rubocop`)
256
+ 3. Add tests for new functionality
257
+ 4. Update the README and CHANGELOG
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Model Verification Script
5
+ # Downloads and tests all supported models to ensure they work correctly.
6
+ #
7
+ # Usage:
8
+ # ruby scripts/verify_models.rb # Run all model tests
9
+ # ruby scripts/verify_models.rb --quick # Quick test (first model of each type only)
10
+ # ruby scripts/verify_models.rb --type embedding # Test only embedding models
11
+
12
+ require 'bundler/setup'
13
+ require 'fastembed'
14
+ require 'optparse'
15
+
16
+ class ModelVerifier
17
+ COLORS = {
18
+ green: "\e[32m",
19
+ red: "\e[31m",
20
+ yellow: "\e[33m",
21
+ cyan: "\e[36m",
22
+ reset: "\e[0m"
23
+ }.freeze
24
+
25
+ def initialize(quick: false, type: nil)
26
+ @quick = quick
27
+ @type = type
28
+ @results = { passed: [], failed: [], skipped: [] }
29
+ end
30
+
31
+ def run
32
+ puts "#{COLORS[:cyan]}=== FastEmbed Model Verification ==#{COLORS[:reset]}"
33
+ puts "Mode: #{@quick ? 'Quick' : 'Full'}"
34
+ puts
35
+
36
+ verify_embedding_models if should_test?(:embedding)
37
+ verify_sparse_models if should_test?(:sparse)
38
+ verify_late_interaction_models if should_test?(:late_interaction)
39
+ verify_reranker_models if should_test?(:reranker)
40
+ verify_image_models if should_test?(:image)
41
+
42
+ print_summary
43
+ end
44
+
45
+ private
46
+
47
+ def should_test?(model_type)
48
+ @type.nil? || @type.to_sym == model_type
49
+ end
50
+
51
+ def verify_embedding_models
52
+ section("Text Embedding Models")
53
+ models = Fastembed::SUPPORTED_MODELS.keys
54
+ models = [models.first] if @quick
55
+
56
+ models.each do |model_name|
57
+ verify_model(model_name, :embedding) do
58
+ embedding = Fastembed::TextEmbedding.new(model_name: model_name, show_progress: false)
59
+ vectors = embedding.embed(['Hello world', 'Test document']).to_a
60
+
61
+ raise "Expected 2 vectors, got #{vectors.length}" unless vectors.length == 2
62
+ raise "Vector dimension mismatch" unless vectors.first.length == embedding.dim
63
+
64
+ "dim=#{embedding.dim}"
65
+ end
66
+ end
67
+ end
68
+
69
+ def verify_sparse_models
70
+ section("Sparse Embedding Models")
71
+ models = Fastembed::SUPPORTED_SPARSE_MODELS.keys
72
+ models = [models.first] if @quick
73
+
74
+ models.each do |model_name|
75
+ verify_model(model_name, :sparse) do
76
+ embedding = Fastembed::TextSparseEmbedding.new(model_name: model_name, show_progress: false)
77
+ vectors = embedding.embed(['Hello world']).to_a
78
+
79
+ raise "Expected sparse vector with indices" unless vectors.first[:indices].is_a?(Array)
80
+ raise "Expected sparse vector with values" unless vectors.first[:values].is_a?(Array)
81
+
82
+ "nnz=#{vectors.first[:indices].length}"
83
+ end
84
+ end
85
+ end
86
+
87
+ def verify_late_interaction_models
88
+ section("Late Interaction Models")
89
+ models = Fastembed::SUPPORTED_LATE_INTERACTION_MODELS.keys
90
+ models = [models.first] if @quick
91
+
92
+ models.each do |model_name|
93
+ verify_model(model_name, :late_interaction) do
94
+ embedding = Fastembed::LateInteractionTextEmbedding.new(model_name: model_name, show_progress: false)
95
+ vectors = embedding.embed(['Hello world']).to_a
96
+
97
+ raise "Expected token embeddings array" unless vectors.first.is_a?(Array)
98
+ raise "Token embedding dimension mismatch" unless vectors.first.first.length == embedding.dim
99
+
100
+ "dim=#{embedding.dim}, tokens=#{vectors.first.length}"
101
+ end
102
+ end
103
+ end
104
+
105
+ def verify_reranker_models
106
+ section("Reranker Models")
107
+ models = Fastembed::SUPPORTED_RERANKER_MODELS.keys
108
+ models = [models.first] if @quick
109
+
110
+ models.each do |model_name|
111
+ verify_model(model_name, :reranker) do
112
+ encoder = Fastembed::TextCrossEncoder.new(model_name: model_name, show_progress: false)
113
+ results = encoder.rerank_with_scores(
114
+ query: 'What is Ruby?',
115
+ documents: ['Ruby is a programming language', 'The sky is blue']
116
+ )
117
+
118
+ raise "Expected ranked results" unless results.is_a?(Array)
119
+ raise "Expected results with scores" unless results.first.key?(:score)
120
+
121
+ "top_score=#{results.first[:score].round(4)}"
122
+ end
123
+ end
124
+ end
125
+
126
+ def verify_image_models
127
+ section("Image Embedding Models")
128
+
129
+ begin
130
+ require 'mini_magick'
131
+ rescue LoadError
132
+ puts "#{COLORS[:yellow]} Skipped (mini_magick not installed)#{COLORS[:reset]}"
133
+ Fastembed::SUPPORTED_IMAGE_MODELS.keys.each do |model_name|
134
+ @results[:skipped] << { name: model_name, type: :image, reason: 'mini_magick not installed' }
135
+ end
136
+ return
137
+ end
138
+
139
+ models = Fastembed::SUPPORTED_IMAGE_MODELS.keys
140
+ models = [models.first] if @quick
141
+
142
+ models.each do |model_name|
143
+ verify_model(model_name, :image) do
144
+ # Create a test image
145
+ require 'tempfile'
146
+ path = Tempfile.new(['test', '.png']).path
147
+ MiniMagick::Tool::Convert.new do |convert|
148
+ convert.size '224x224'
149
+ convert.xc 'white'
150
+ convert << path
151
+ end
152
+
153
+ begin
154
+ embedding = Fastembed::ImageEmbedding.new(model_name: model_name, show_progress: false)
155
+ vectors = embedding.embed(path).to_a
156
+
157
+ raise "Expected image embedding" unless vectors.first.is_a?(Array)
158
+ raise "Dimension mismatch" unless vectors.first.length == embedding.dim
159
+
160
+ "dim=#{embedding.dim}"
161
+ ensure
162
+ File.delete(path) if File.exist?(path)
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def verify_model(model_name, type)
169
+ print " #{model_name}... "
170
+ $stdout.flush
171
+
172
+ start_time = Time.now
173
+ begin
174
+ result = yield
175
+ elapsed = (Time.now - start_time).round(2)
176
+ puts "#{COLORS[:green]}PASS#{COLORS[:reset]} (#{elapsed}s) [#{result}]"
177
+ @results[:passed] << { name: model_name, type: type, time: elapsed }
178
+ rescue => e
179
+ elapsed = (Time.now - start_time).round(2)
180
+ puts "#{COLORS[:red]}FAIL#{COLORS[:reset]} (#{elapsed}s)"
181
+ puts " Error: #{e.message}"
182
+ @results[:failed] << { name: model_name, type: type, error: e.message }
183
+ end
184
+ end
185
+
186
+ def section(title)
187
+ puts "#{COLORS[:cyan]}#{title}:#{COLORS[:reset]}"
188
+ end
189
+
190
+ def print_summary
191
+ puts
192
+ puts "#{COLORS[:cyan]}=== Summary ==#{COLORS[:reset]}"
193
+ puts "Passed: #{COLORS[:green]}#{@results[:passed].length}#{COLORS[:reset]}"
194
+ puts "Failed: #{COLORS[:red]}#{@results[:failed].length}#{COLORS[:reset]}"
195
+ puts "Skipped: #{COLORS[:yellow]}#{@results[:skipped].length}#{COLORS[:reset]}"
196
+ puts
197
+
198
+ unless @results[:failed].empty?
199
+ puts "#{COLORS[:red]}Failed models:#{COLORS[:reset]}"
200
+ @results[:failed].each do |r|
201
+ puts " - #{r[:name]} (#{r[:type]}): #{r[:error]}"
202
+ end
203
+ end
204
+
205
+ exit(@results[:failed].empty? ? 0 : 1)
206
+ end
207
+ end
208
+
209
+ # Parse options
210
+ options = { quick: false, type: nil }
211
+ OptionParser.new do |opts|
212
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
213
+
214
+ opts.on('-q', '--quick', 'Quick mode (first model of each type only)') do
215
+ options[:quick] = true
216
+ end
217
+
218
+ opts.on('-t', '--type TYPE', %w[embedding sparse late_interaction reranker image],
219
+ 'Test only models of this type') do |type|
220
+ options[:type] = type
221
+ end
222
+
223
+ opts.on('-h', '--help', 'Show this help') do
224
+ puts opts
225
+ exit
226
+ end
227
+ end.parse!
228
+
229
+ ModelVerifier.new(**options).run
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastembed
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hasinski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-08 00:00:00.000000000 Z
11
+ date: 2026-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: onnxruntime
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mini_magick
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,30 +108,83 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.9'
97
139
  description: A Ruby port of FastEmbed - fast text embeddings using ONNX Runtime
98
140
  email:
99
141
  - krzysztof.hasinski@gmail.com
100
- executables: []
142
+ executables:
143
+ - fastembed
101
144
  extensions: []
102
145
  extra_rdoc_files: []
103
146
  files:
104
147
  - ".mise.toml"
105
148
  - ".rspec"
106
149
  - ".rubocop.yml"
150
+ - ".yardopts"
107
151
  - BENCHMARKS.md
108
152
  - CHANGELOG.md
109
153
  - Gemfile
110
154
  - LICENSE
111
155
  - README.md
112
156
  - Rakefile
157
+ - benchmark/compare_all.rb
158
+ - benchmark/compare_python.py
159
+ - benchmark/memory_profile.rb
160
+ - benchmark/profile.rb
161
+ - benchmark/reranker_benchmark.rb
162
+ - exe/fastembed
113
163
  - fastembed.gemspec
114
164
  - lib/fastembed.rb
165
+ - lib/fastembed/async.rb
166
+ - lib/fastembed/base_model.rb
167
+ - lib/fastembed/base_model_info.rb
168
+ - lib/fastembed/cli.rb
169
+ - lib/fastembed/custom_model_registry.rb
170
+ - lib/fastembed/image_embedding.rb
171
+ - lib/fastembed/late_interaction_embedding.rb
172
+ - lib/fastembed/late_interaction_model_info.rb
115
173
  - lib/fastembed/model_info.rb
116
174
  - lib/fastembed/model_management.rb
117
175
  - lib/fastembed/onnx_embedding_model.rb
118
176
  - lib/fastembed/pooling.rb
177
+ - lib/fastembed/progress.rb
178
+ - lib/fastembed/quantization.rb
179
+ - lib/fastembed/reranker_model_info.rb
180
+ - lib/fastembed/sparse_embedding.rb
181
+ - lib/fastembed/sparse_model_info.rb
182
+ - lib/fastembed/text_cross_encoder.rb
119
183
  - lib/fastembed/text_embedding.rb
184
+ - lib/fastembed/validators.rb
120
185
  - lib/fastembed/version.rb
186
+ - plan.md
187
+ - scripts/verify_models.rb
121
188
  homepage: https://github.com/khasinski/fastembed-rb
122
189
  licenses:
123
190
  - MIT