main
rb 287 lines 10.1 KB
Raw
1 # This file should ensure the existence of records required to run the application in every environment (production,
2 # development, test). The code here should be idempotent so that it can be executed at any point in every environment.
3 # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
4
5 require "digest"
6 require "open3"
7 require "fileutils"
8 require "tmpdir"
9
10 # ---------------------------------------------------------------------------
11 # Demo model library — seeds a handful of Hugging Face-style model repositories
12 # so the /models discovery page and model pages work out of the box.
13 # ---------------------------------------------------------------------------
14
15 # A Git LFS pointer file: the tiny text stub that stands in for a large weight
16 # file. The UI resolves the real `size` and shows an "LFS" badge.
17 def lfs_pointer(size_bytes, seed)
18 oid = Digest::SHA256.hexdigest("#{seed}-#{size_bytes}")
19 "version https://git-lfs.github.com/spec/v1\noid sha256:#{oid}\nsize #{size_bytes}\n"
20 end
21
22 GB = 1024 * 1024 * 1024
23 MB = 1024 * 1024
24
25 # Pushes README + files into the model's bare repo (idempotent: skips if the
26 # default branch already has commits).
27 def seed_model_files(repo, card:, files:)
28 path = repo.disk_path
29 GitRepositoryService.create_bare_repo(repo.user.username, repo.name) unless repo.initialized?
30 return if GitRepositoryService.branch_exists?(path, repo.default_branch)
31
32 Dir.mktmpdir do |dir|
33 system("git", "-C", dir, "init", "-b", repo.default_branch, exception: true)
34 system("git", "-C", dir, "config", "user.email", "sigitsi@localhost", exception: true)
35 system("git", "-C", dir, "config", "user.name", "siGit", exception: true)
36 # The seed writes Git LFS *pointer* text directly — we do not want the local
37 # git-lfs filter (if installed) to try to clean/upload them as real objects.
38 # Neutralise the LFS filters so the pointer bytes are committed verbatim.
39 %w[clean smudge].each { |f| system("git", "-C", dir, "config", "filter.lfs.#{f}", "cat", exception: true) }
40 system("git", "-C", dir, "config", "filter.lfs.process", "", exception: true)
41 system("git", "-C", dir, "config", "filter.lfs.required", "false", exception: true)
42
43 File.write(File.join(dir, "README.md"), card)
44 File.write(File.join(dir, ".gitattributes"),
45 "*.gguf filter=lfs diff=lfs merge=lfs -text\n*.safetensors filter=lfs diff=lfs merge=lfs -text\n")
46 files.each do |f|
47 full = File.join(dir, f[:path])
48 FileUtils.mkdir_p(File.dirname(full))
49 File.write(full, f[:content])
50 end
51
52 system("git", "-C", dir, "add", ".", exception: true)
53 system("git", "-C", dir, "commit", "-m", "Upload model", exception: true)
54 system("git", "-C", dir, "remote", "add", "origin", path, exception: true)
55 system("git", "-C", dir, "push", "origin", repo.default_branch, exception: true)
56 end
57 end
58
59 def seed_model(username:, email:, smbcloud_id:, name:, description:, card:, files:, downloads:, likes:, updated_at: Time.current)
60 user = User.find_or_create_by!(smbcloud_id: smbcloud_id) do |u|
61 u.username = username
62 u.email = email
63 end
64
65 repo = user.repositories.find_or_initialize_by(name: name)
66 repo.assign_attributes(
67 kind: "model",
68 description: description,
69 default_branch: "main",
70 disk_path: GitRepositoryService.repo_path(username, name),
71 downloads_count: downloads,
72 stars_count: likes,
73 updated_at: updated_at
74 )
75 repo.save!
76
77 seed_model_files(repo, card: card, files: files)
78 repo
79 rescue => e
80 warn " ! Skipped #{username}/#{name}: #{e.message}"
81 nil
82 end
83
84 # ── bartowski/Qwen2.5-3B-Instruct-GGUF (the showcase model) ──
85 qwen_card = <<~MD
86 ---
87 license: apache-2.0
88 base_model: Qwen/Qwen2.5-3B-Instruct
89 pipeline_tag: text-generation
90 library_name: gguf
91 language:
92 - en
93 tags:
94 - text-generation
95 - gguf
96 - quantized
97 - qwen2.5
98 ---
99
100 # Qwen2.5-3B-Instruct-GGUF
101
102 GGUF quantizations of [Qwen/Qwen2.5-3B-Instruct](https://sigit.si/qwen/Qwen2.5-3B-Instruct),
103 produced with `llama.cpp`. Pick a quant that fits your hardware — higher bits
104 mean better quality, lower bits mean a smaller file and faster inference.
105
106 ## Quant table
107
108 | File | Quant | Size | Notes |
109 | ---- | ----- | ---- | ----- |
110 | `Qwen2.5-3B-Instruct-Q8_0.gguf` | Q8_0 | 3.3 GB | Near-lossless, recommended for quality |
111 | `Qwen2.5-3B-Instruct-Q5_K_M.gguf` | Q5_K_M | 2.2 GB | Balanced quality / size |
112 | `Qwen2.5-3B-Instruct-Q4_K_M.gguf` | Q4_K_M | 1.9 GB | Good default for most setups |
113 | `Qwen2.5-3B-Instruct-Q3_K_M.gguf` | Q3_K_M | 1.6 GB | Smallest, some quality loss |
114
115 ## Run it
116
117 ```bash
118 llama-cli -hf bartowski/Qwen2.5-3B-Instruct-GGUF -p "Hello!"
119 ```
120
121 ## Prompt format
122
123 ```
124 <|im_start|>system
125 You are a helpful assistant.<|im_end|>
126 <|im_start|>user
127 {prompt}<|im_end|>
128 <|im_start|>assistant
129 ```
130 MD
131
132 qwen_files = [
133 { path: "Qwen2.5-3B-Instruct-Q8_0.gguf", content: lfs_pointer((3.3 * GB).to_i, "q8") },
134 { path: "Qwen2.5-3B-Instruct-Q5_K_M.gguf", content: lfs_pointer((2.2 * GB).to_i, "q5") },
135 { path: "Qwen2.5-3B-Instruct-Q4_K_M.gguf", content: lfs_pointer((1.9 * GB).to_i, "q4") },
136 { path: "Qwen2.5-3B-Instruct-Q3_K_M.gguf", content: lfs_pointer((1.6 * GB).to_i, "q3") },
137 { path: "config.json", content: %({\n "model_type": "qwen2",\n "quantized_by": "bartowski"\n}\n) }
138 ]
139
140 seed_model(
141 username: "bartowski", email: "bartowski@example.com", smbcloud_id: 900_001,
142 name: "Qwen2.5-3B-Instruct-GGUF",
143 description: "GGUF quants of Qwen2.5-3B-Instruct for llama.cpp.",
144 card: qwen_card, files: qwen_files,
145 downloads: 1_284_530, likes: 412, updated_at: 2.weeks.ago
146 )
147
148 # ── meta-llama/Llama-3.2-1B-Instruct (safetensors / transformers) ──
149 llama_card = <<~MD
150 ---
151 license: llama3.2
152 base_model: meta-llama/Llama-3.2-1B
153 pipeline_tag: text-generation
154 library_name: transformers
155 language:
156 - en
157 tags:
158 - text-generation
159 - llama
160 - instruct
161 ---
162
163 # Llama-3.2-1B-Instruct
164
165 A compact 1B instruction-tuned model. Load it with 🤗 Transformers:
166
167 ```python
168 from transformers import AutoModelForCausalLM, AutoTokenizer
169
170 model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B-Instruct")
171 tok = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-1B-Instruct")
172 ```
173 MD
174
175 llama_files = [
176 { path: "model.safetensors", content: lfs_pointer((2.5 * GB).to_i, "llama-st") },
177 { path: "config.json", content: %({\n "model_type": "llama",\n "hidden_size": 2048\n}\n) },
178 { path: "tokenizer.json", content: lfs_pointer((9 * MB).to_i, "llama-tok") },
179 { path: "generation_config.json", content: %({\n "temperature": 0.6,\n "top_p": 0.9\n}\n) }
180 ]
181
182 seed_model(
183 username: "meta-llama", email: "meta-llama@example.com", smbcloud_id: 900_002,
184 name: "Llama-3.2-1B-Instruct",
185 description: "Lightweight 1B instruction-tuned text model.",
186 card: llama_card, files: llama_files,
187 downloads: 3_902_117, likes: 1_287, updated_at: 5.days.ago
188 )
189
190 # ── sentence-transformers/all-MiniLM-L6-v2 (embeddings) ──
191 minilm_card = <<~MD
192 ---
193 license: apache-2.0
194 pipeline_tag: sentence-similarity
195 library_name: sentence-transformers
196 tags:
197 - sentence-similarity
198 - feature-extraction
199 - embeddings
200 ---
201
202 # all-MiniLM-L6-v2
203
204 Maps sentences and paragraphs to a 384-dimensional dense vector space for
205 semantic search, clustering, and retrieval.
206
207 ```python
208 from sentence_transformers import SentenceTransformer
209 model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
210 emb = model.encode(["A sentence to embed."])
211 ```
212 MD
213
214 minilm_files = [
215 { path: "model.safetensors", content: lfs_pointer((90 * MB).to_i, "minilm-st") },
216 { path: "config.json", content: %({\n "model_type": "bert",\n "hidden_size": 384\n}\n) },
217 { path: "tokenizer.json", content: lfs_pointer((700 * 1024).to_i, "minilm-tok") }
218 ]
219
220 seed_model(
221 username: "sentence-transformers", email: "st@example.com", smbcloud_id: 900_003,
222 name: "all-MiniLM-L6-v2",
223 description: "384-dim sentence embeddings for semantic search.",
224 card: minilm_card, files: minilm_files,
225 downloads: 8_450_990, likes: 2_034, updated_at: 1.month.ago
226 )
227
228 # ── A model published by the demo @sigit profile, so its Models tab has content ──
229 # Attaches to the existing "sigit" user rather than creating one. On-brand: a
230 # small code-completion model the platform ships itself.
231 if (sigit = User.find_by(username: "sigit"))
232 sigit_card = <<~MD
233 ---
234 license: apache-2.0
235 base_model: Qwen/Qwen2.5-Coder-1.5B
236 pipeline_tag: text-generation
237 library_name: gguf
238 language:
239 - en
240 tags:
241 - text-generation
242 - code
243 - code-completion
244 - gguf
245 ---
246
247 # SiGit-Coder-1.5B-GGUF
248
249 A small, fast code-completion model that powers inline suggestions in the
250 siGit Code & Deploy editor. GGUF quantizations run locally with `llama.cpp`,
251 so completions stay on your machine.
252
253 ## Quant table
254
255 | File | Quant | Size | Notes |
256 | ---- | ----- | ---- | ----- |
257 | `SiGit-Coder-1.5B-Q8_0.gguf` | Q8_0 | 1.6 GB | Best quality |
258 | `SiGit-Coder-1.5B-Q5_K_M.gguf` | Q5_K_M | 1.1 GB | Balanced |
259 | `SiGit-Coder-1.5B-Q4_K_M.gguf` | Q4_K_M | 1.0 GB | Recommended default |
260
261 ## Run it
262
263 ```bash
264 llama-cli -hf sigit/SiGit-Coder-1.5B-GGUF -p "def fib(n):"
265 ```
266 MD
267
268 sigit_files = [
269 { path: "SiGit-Coder-1.5B-Q8_0.gguf", content: lfs_pointer((1.6 * GB).to_i, "sigit-q8") },
270 { path: "SiGit-Coder-1.5B-Q5_K_M.gguf", content: lfs_pointer((1.1 * GB).to_i, "sigit-q5") },
271 { path: "SiGit-Coder-1.5B-Q4_K_M.gguf", content: lfs_pointer((1.0 * GB).to_i, "sigit-q4") },
272 { path: "config.json", content: %({\n "model_type": "qwen2",\n "quantized_by": "sigit"\n}\n) }
273 ]
274
275 repo = sigit.repositories.find_or_initialize_by(name: "SiGit-Coder-1.5B-GGUF")
276 repo.assign_attributes(
277 kind: "model",
278 description: "Local code-completion model behind the siGit editor's inline suggestions.",
279 default_branch: "main",
280 disk_path: GitRepositoryService.repo_path(sigit.username, "SiGit-Coder-1.5B-GGUF"),
281 downloads_count: 47_213, stars_count: 96, updated_at: 4.days.ago
282 )
283 repo.save!
284 seed_model_files(repo, card: sigit_card, files: sigit_files)
285 end
286
287 puts "Seeded #{Repository.models.count} model repositories."