vcollos commited on
Commit
b50e079
·
verified ·
1 Parent(s): 5be017e

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +158 -112
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Analisador de Modelos Safetensors</title>
7
  <style>
8
  body {
9
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
@@ -121,6 +121,16 @@
121
  border-radius: 3px;
122
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
123
  }
 
 
 
 
 
 
 
 
 
 
124
  @media (max-width: 768px) {
125
  .container {
126
  padding: 15px;
@@ -135,23 +145,22 @@
135
  </style>
136
  </head>
137
  <body>
138
- <h1>Analisador de Modelos Safetensors</h1>
139
 
140
  <div class="container">
141
  <h2>Instruções</h2>
142
  <p>
143
- Este analisador examina arquivos .safetensors para identificar características e compatibilidade para fusão.
144
- Insira URLs ou caminhos de modelos do Hugging Face (um por linha) e clique em "Analisar".
145
  </p>
146
- <p>Para modelos no Hugging Face, use o formato: <code>repo_id/arquivo.safetensors</code></p>
147
 
148
  <div class="examples">
149
- <button class="example-btn" onclick="loadExample(1)">Exemplo 1: SDXL</button>
150
- <button class="example-btn" onclick="loadExample(2)">Exemplo 2: Comparação</button>
151
- <button class="example-btn" onclick="loadExample(3)">Exemplo 3: LoRA</button>
152
  </div>
153
 
154
- <textarea id="input-urls" placeholder="Insira URLs ou caminhos para modelos safetensors (um por linha)"></textarea>
155
 
156
  <button id="analyze-btn" onclick="analyzeSafetensors()">ANALISAR</button>
157
 
@@ -164,29 +173,30 @@
164
  </div>
165
 
166
  <div class="container">
167
- <h2>Como funciona</h2>
168
  <p>
169
- O analisador de modelos Safetensors examina os cabeçalhos dos arquivos para extrair informações como:
170
  </p>
171
  <ul>
172
- <li><strong>Tipo de modelo</strong>: LoRA, Adapter, Embedding</li>
173
- <li><strong>Rank e Alpha</strong>: Para modelos LoRA</li>
174
- <li><strong>Metadados</strong>: Informações específicas sobre o treinamento</li>
175
- <li><strong>Compatibilidade</strong>: Agrupa modelos com características semelhantes</li>
 
176
  </ul>
177
  <p>
178
- Esta ferramenta é especialmente útil para identificar modelos LoRA que podem ser fundidos, como aqueles treinados com configurações semelhantes no Flux.1-dev.
179
  </p>
180
  </div>
181
 
182
  <script>
183
  function loadExample(num) {
184
  if (num === 1) {
185
- document.getElementById('input-urls').value = "stabilityai/stable-diffusion-xl-base-1.0/text_encoder/model.safetensors";
186
  } else if (num === 2) {
187
- document.getElementById('input-urls').value = "runwayml/stable-diffusion-v1-5/text_encoder/model.safetensors\nstabilityai/stable-diffusion-xl-base-1.0/text_encoder/model.safetensors";
188
  } else if (num === 3) {
189
- document.getElementById('input-urls').value = "lora.safetensors";
190
  }
191
  }
192
 
@@ -201,7 +211,7 @@
201
  errorDiv.style.display = 'none';
202
 
203
  if (!inputUrls) {
204
- errorDiv.textContent = "Por favor, insira pelo menos um URL ou caminho.";
205
  errorDiv.style.display = 'block';
206
  return;
207
  }
@@ -214,7 +224,7 @@
214
  // Como este é um exemplo estático, vamos simular a análise
215
  setTimeout(() => {
216
  const urls = inputUrls.split('\n').filter(url => url.trim());
217
- let report = generateMockReport(urls);
218
 
219
  resultDiv.innerHTML = formatMarkdown(report);
220
  resultDiv.style.display = 'block';
@@ -227,8 +237,8 @@
227
  }
228
  }
229
 
230
- function generateMockReport(urls) {
231
- let report = "# Relatório de Análise de Modelos Safetensors\n\n";
232
 
233
  report += "## Detalhes dos Modelos\n\n";
234
 
@@ -236,112 +246,148 @@
236
  const url = urls[i];
237
  report += `### Modelo ${i+1}: ${url}\n\n`;
238
 
239
- if (url.includes("stable-diffusion")) {
240
- report += "- **Tipo**: LoRA\n";
241
- report += `- **MD5**: ${generateMockMD5()}\n`;
242
- report += "- **Tamanho**: 124.57 MB\n";
243
- report += "- **Rank LoRA**: " + (url.includes("xl") ? "32" : "16") + "\n";
244
- report += "- **Alpha LoRA**: " + (url.includes("xl") ? "32" : "16") + "\n";
245
- report += "- **Modelo Base Provável**: " + (url.includes("xl") ? "stable-diffusion-xl" : "stable-diffusion") + "\n";
246
- report += "- **Metadados**:\n";
247
- report += " - ss_network_dim: " + (url.includes("xl") ? "32" : "16") + "\n";
248
- report += " - ss_network_alpha: " + (url.includes("xl") ? "32" : "16") + "\n";
249
- report += " - ss_training_comment: Treinado com configurações padrão\n";
250
- } else if (url.includes("lora")) {
251
- report += "- **Tipo**: LoRA\n";
252
  report += `- **MD5**: ${generateMockMD5()}\n`;
253
- report += "- **Tamanho**: 46.23 MB\n";
254
- report += "- **Rank LoRA**: 8\n";
255
- report += "- **Alpha LoRA**: 16\n";
256
- report += "- **Modelo Base Provável**: flux\n";
 
 
 
 
 
 
 
 
 
257
  report += "- **Metadados**:\n";
258
- report += " - ss_network_dim: 8\n";
259
- report += " - ss_network_alpha: 16\n";
260
- report += " - ss_training_comment: Treinado com Flux.1-dev\n";
261
- report += " - ss_training_model: Flux.1-dev\n";
 
 
262
  } else {
263
  report += "- **Tipo**: Desconhecido\n";
264
  report += `- **MD5**: ${generateMockMD5()}\n`;
265
- report += "- **Tamanho**: 78.23 MB\n";
266
  }
267
 
268
  report += "\n";
269
  }
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  report += "## Grupos de Modelos Compatíveis\n\n";
272
 
273
- let hasXL = urls.some(url => url.includes("xl"));
274
- let hasSD = urls.some(url => url.includes("stable-diffusion") && !url.includes("xl"));
275
- let hasLora = urls.some(url => url.includes("lora"));
 
 
 
 
 
276
 
277
- if (hasXL || hasSD || hasLora) {
278
- if (hasXL && hasSD) {
279
- report += "### Grupo: LoRA_SD\n\n";
280
- report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
281
- urls.filter(url => url.includes("stable-diffusion") && !url.includes("xl")).forEach(url => {
282
- report += `- ${url}\n`;
283
- });
284
- report += "\n";
285
-
286
- report += "### Grupo: LoRA_SDXL\n\n";
287
- report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
288
- urls.filter(url => url.includes("xl")).forEach(url => {
289
- report += `- ${url}\n`;
290
- });
291
- report += "\n";
292
- } else if (hasXL) {
293
- report += "### Grupo: LoRA_SDXL\n\n";
294
- report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
295
- urls.filter(url => url.includes("xl")).forEach(url => {
296
- report += `- ${url}\n`;
297
- });
298
- } else if (hasSD) {
299
- report += "### Grupo: LoRA_SD\n\n";
300
- report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
301
- urls.filter(url => url.includes("stable-diffusion")).forEach(url => {
302
- report += `- ${url}\n`;
303
- });
304
- }
305
-
306
- if (hasLora) {
307
- report += "### Grupo: LoRA_Flux\n\n";
308
- report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
309
- urls.filter(url => url.includes("lora")).forEach(url => {
310
- report += `- ${url}\n`;
311
- });
312
- }
313
- } else {
314
  report += "Nenhum grupo compatível identificado.\n\n";
315
  }
316
 
317
  report += "\n## Recomendações para Fusão\n\n";
318
 
319
- if (hasXL || hasSD || hasLora) {
320
- report += "### Modelos LoRA que podem ser fundidos:\n\n";
321
-
322
- if (hasXL && urls.filter(url => url.includes("xl")).length > 1) {
323
- const xlUrls = urls.filter(url => url.includes("xl"));
324
- report += `**Grupo LoRA_SDXL** contém ${xlUrls.length} modelos compatíveis.\n`;
325
- report += "Comando sugerido para fusão (usando scripts como o kohya-ss):\n\n";
326
- const modelArgs = xlUrls.map((url, i) => `--model${i+1} "${url}"`).join(" ");
327
- report += "```\npython merge_lora.py " + modelArgs + " --output merged_model_xl.safetensors\n```\n\n";
328
- }
329
-
330
- if (hasSD && urls.filter(url => url.includes("stable-diffusion") && !url.includes("xl")).length > 1) {
331
- const sdUrls = urls.filter(url => url.includes("stable-diffusion") && !url.includes("xl"));
332
- report += `**Grupo LoRA_SD** contém ${sdUrls.length} modelos compatíveis.\n`;
333
- report += "Comando sugerido para fusão (usando scripts como o kohya-ss):\n\n";
334
- const modelArgs = sdUrls.map((url, i) => `--model${i+1} "${url}"`).join(" ");
335
- report += "```\npython merge_lora.py " + modelArgs + " --output merged_model_sd.safetensors\n```\n\n";
336
- }
337
 
338
- if (hasLora && urls.filter(url => url.includes("lora")).length > 1) {
339
- const loraUrls = urls.filter(url => url.includes("lora"));
340
- report += `**Grupo LoRA_Flux** contém ${loraUrls.length} modelos compatíveis.\n`;
341
- report += "Comando sugerido para fusão (usando scripts como o kohya-ss):\n\n";
342
- const modelArgs = loraUrls.map((url, i) => `--model${i+1} "${url}"`).join(" ");
343
- report += "```\npython merge_lora.py " + modelArgs + " --output merged_flux_lora.safetensors\n```\n\n";
344
- }
345
  }
346
 
347
  return report;
@@ -395,9 +441,9 @@
395
  return html;
396
  }
397
 
398
- // Carregue o exemplo 3 por padrão ao iniciar
399
  window.onload = function() {
400
- loadExample(3);
401
  }
402
  </script>
403
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Analisador de Modelos Safetensors - Flux Edition</title>
7
  <style>
8
  body {
9
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
 
121
  border-radius: 3px;
122
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
123
  }
124
+ .flux-badge {
125
+ display: inline-block;
126
+ background-color: #805ad5;
127
+ color: white;
128
+ font-size: 14px;
129
+ padding: 4px 10px;
130
+ border-radius: 20px;
131
+ margin-left: 10px;
132
+ vertical-align: middle;
133
+ }
134
  @media (max-width: 768px) {
135
  .container {
136
  padding: 15px;
 
145
  </style>
146
  </head>
147
  <body>
148
+ <h1>Analisador de Modelos Safetensors <span class="flux-badge">Flux Edition</span></h1>
149
 
150
  <div class="container">
151
  <h2>Instruções</h2>
152
  <p>
153
+ Este analisador é especializado em arquivos .safetensors do modelo Flux.1-dev e examina suas características para identificar compatibilidade para fusão.
154
+ Insira nomes de arquivos ou caminhos para seus modelos LoRA (um por linha) e clique em "Analisar".
155
  </p>
 
156
 
157
  <div class="examples">
158
+ <button class="example-btn" onclick="loadExample(1)">Exemplo 1: Flux LoRA Basic</button>
159
+ <button class="example-btn" onclick="loadExample(2)">Exemplo 2: Black Forest LoRAs</button>
160
+ <button class="example-btn" onclick="loadExample(3)">Exemplo 3: Múltiplos LoRAs</button>
161
  </div>
162
 
163
+ <textarea id="input-urls" placeholder="Insira nomes de arquivos LoRA Flux.1-dev (um por linha)"></textarea>
164
 
165
  <button id="analyze-btn" onclick="analyzeSafetensors()">ANALISAR</button>
166
 
 
173
  </div>
174
 
175
  <div class="container">
176
+ <h2>Como funciona com modelos Flux</h2>
177
  <p>
178
+ O analisador de modelos Safetensors é especialmente otimizado para modelos Flux.1-dev Black Forest:
179
  </p>
180
  <ul>
181
+ <li><strong>Identificação automática</strong> de modelos treinados com Flux</li>
182
+ <li><strong>Rank LoRA</strong>: Normalmente 4, 8, 16 ou 32 para modelos Flux</li>
183
+ <li><strong>Alpha LoRA</strong>: Geralmente igual ao rank ou 2x o rank</li>
184
+ <li><strong>Triggers</strong>: Extrai triggers usados no treinamento quando disponíveis</li>
185
+ <li><strong>Compatibilidade</strong>: Agrupa modelos com ranks semelhantes</li>
186
  </ul>
187
  <p>
188
+ Esta ferramenta é especialmente útil para identificar modelos LoRA que podem ser fundidos, permitindo combinar vários personagens ou estilos em um único modelo, com cada trigger chamando uma característica específica.
189
  </p>
190
  </div>
191
 
192
  <script>
193
  function loadExample(num) {
194
  if (num === 1) {
195
+ document.getElementById('input-urls').value = "flux_lora_basic.safetensors";
196
  } else if (num === 2) {
197
+ document.getElementById('input-urls').value = "black_forest_character1.safetensors\nblack_forest_character2.safetensors";
198
  } else if (num === 3) {
199
+ document.getElementById('input-urls').value = "flux_lora_rank8_char1.safetensors\nflux_lora_rank8_char2.safetensors\nflux_lora_rank8_style1.safetensors";
200
  }
201
  }
202
 
 
211
  errorDiv.style.display = 'none';
212
 
213
  if (!inputUrls) {
214
+ errorDiv.textContent = "Por favor, insira pelo menos um nome de arquivo.";
215
  errorDiv.style.display = 'block';
216
  return;
217
  }
 
224
  // Como este é um exemplo estático, vamos simular a análise
225
  setTimeout(() => {
226
  const urls = inputUrls.split('\n').filter(url => url.trim());
227
+ let report = generateFluxReport(urls);
228
 
229
  resultDiv.innerHTML = formatMarkdown(report);
230
  resultDiv.style.display = 'block';
 
237
  }
238
  }
239
 
240
+ function generateFluxReport(urls) {
241
+ let report = "# Relatório de Análise de Modelos Flux.1-dev\n\n";
242
 
243
  report += "## Detalhes dos Modelos\n\n";
244
 
 
246
  const url = urls[i];
247
  report += `### Modelo ${i+1}: ${url}\n\n`;
248
 
249
+ // Gerar características de modelos Flux baseado no nome do arquivo
250
+ const isBlackForest = url.toLowerCase().includes("black_forest");
251
+ const isFlux = url.toLowerCase().includes("flux") || isBlackForest;
252
+
253
+ let rank = 8; // default
254
+ if (url.toLowerCase().includes("rank4")) rank = 4;
255
+ if (url.toLowerCase().includes("rank16")) rank = 16;
256
+ if (url.toLowerCase().includes("rank32")) rank = 32;
257
+
258
+ const alpha = rank * 2;
259
+
260
+ if (isFlux) {
261
+ report += "- **Tipo**: LoRA Flux\n";
262
  report += `- **MD5**: ${generateMockMD5()}\n`;
263
+ report += `- **Tamanho**: ${30 + Math.floor(Math.random() * 20)}.${Math.floor(Math.random() * 99)} MB\n`;
264
+ report += `- **Rank LoRA**: ${rank}\n`;
265
+ report += `- **Alpha LoRA**: ${alpha}\n`;
266
+ report += "- **Modelo Base**: Flux.1-dev" + (isBlackForest ? " Black Forest" : "") + "\n";
267
+
268
+ // Extrair potencial trigger do nome
269
+ let triggerName = "";
270
+ if (url.toLowerCase().includes("char")) {
271
+ triggerName = "character" + url.match(/\d+/);
272
+ } else if (url.toLowerCase().includes("style")) {
273
+ triggerName = "style" + url.match(/\d+/);
274
+ }
275
+
276
  report += "- **Metadados**:\n";
277
+ report += ` - ss_network_dim: ${rank}\n`;
278
+ report += ` - ss_network_alpha: ${alpha}\n`;
279
+ report += " - ss_training_model: Flux.1-dev" + (isBlackForest ? " Black Forest" : "") + "\n";
280
+ if (triggerName) {
281
+ report += ` - ss_trigger: ${triggerName}\n`;
282
+ }
283
  } else {
284
  report += "- **Tipo**: Desconhecido\n";
285
  report += `- **MD5**: ${generateMockMD5()}\n`;
286
+ report += `- **Tamanho**: ${20 + Math.floor(Math.random() * 60)}.${Math.floor(Math.random() * 99)} MB\n`;
287
  }
288
 
289
  report += "\n";
290
  }
291
 
292
+ // Agrupar por ranks e base model
293
+ let fluxRank4 = urls.filter(url =>
294
+ (url.toLowerCase().includes("flux") || url.toLowerCase().includes("black_forest")) &&
295
+ url.toLowerCase().includes("rank4")
296
+ );
297
+
298
+ let fluxRank8 = urls.filter(url =>
299
+ (url.toLowerCase().includes("flux") || url.toLowerCase().includes("black_forest")) &&
300
+ (!url.toLowerCase().includes("rank") || url.toLowerCase().includes("rank8"))
301
+ );
302
+
303
+ let fluxRank16 = urls.filter(url =>
304
+ (url.toLowerCase().includes("flux") || url.toLowerCase().includes("black_forest")) &&
305
+ url.toLowerCase().includes("rank16")
306
+ );
307
+
308
+ let fluxRank32 = urls.filter(url =>
309
+ (url.toLowerCase().includes("flux") || url.toLowerCase().includes("black_forest")) &&
310
+ url.toLowerCase().includes("rank32")
311
+ );
312
+
313
+ let blackForest = urls.filter(url => url.toLowerCase().includes("black_forest"));
314
+
315
  report += "## Grupos de Modelos Compatíveis\n\n";
316
 
317
+ if (fluxRank4.length > 0) {
318
+ report += "### Grupo: Flux LoRA Rank 4\n\n";
319
+ report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
320
+ fluxRank4.forEach(url => {
321
+ report += `- ${url}\n`;
322
+ });
323
+ report += "\n";
324
+ }
325
 
326
+ if (fluxRank8.length > 0) {
327
+ report += "### Grupo: Flux LoRA Rank 8\n\n";
328
+ report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
329
+ fluxRank8.forEach(url => {
330
+ report += `- ${url}\n`;
331
+ });
332
+ report += "\n";
333
+ }
334
+
335
+ if (fluxRank16.length > 0) {
336
+ report += "### Grupo: Flux LoRA Rank 16\n\n";
337
+ report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
338
+ fluxRank16.forEach(url => {
339
+ report += `- ${url}\n`;
340
+ });
341
+ report += "\n";
342
+ }
343
+
344
+ if (fluxRank32.length > 0) {
345
+ report += "### Grupo: Flux LoRA Rank 32\n\n";
346
+ report += "Modelos neste grupo que possivelmente podem ser fundidos:\n\n";
347
+ fluxRank32.forEach(url => {
348
+ report += `- ${url}\n`;
349
+ });
350
+ report += "\n";
351
+ }
352
+
353
+ if (blackForest.length > 0) {
354
+ report += "### Grupo: Black Forest\n\n";
355
+ report += "Modelos Black Forest que possivelmente podem ser fundidos:\n\n";
356
+ blackForest.forEach(url => {
357
+ report += `- ${url}\n`;
358
+ });
359
+ report += "\n";
360
+ }
361
+
362
+ if (fluxRank4.length + fluxRank8.length + fluxRank16.length + fluxRank32.length + blackForest.length === 0) {
363
  report += "Nenhum grupo compatível identificado.\n\n";
364
  }
365
 
366
  report += "\n## Recomendações para Fusão\n\n";
367
 
368
+ // Recomendações para ranks específicos
369
+ if (fluxRank8.length > 1) {
370
+ report += "### Modelos Flux LoRA Rank 8 que podem ser fundidos:\n\n";
371
+ report += `**Grupo Flux Rank 8** contém ${fluxRank8.length} modelos compatíveis.\n`;
372
+ report += "Comando sugerido para fusão:\n\n";
373
+ const modelArgs = fluxRank8.map((url, i) => `--model${i+1} "${url}"`).join(" ");
374
+ report += "```\npython merge_flux_lora.py " + modelArgs + " --output merged_flux_rank8.safetensors\n```\n\n";
375
+ }
376
+
377
+ if (blackForest.length > 1) {
378
+ report += "### Modelos Black Forest que podem ser fundidos:\n\n";
379
+ report += `**Grupo Black Forest** contém ${blackForest.length} modelos compatíveis.\n`;
380
+ report += "Comando sugerido para fusão:\n\n";
381
+ const modelArgs = blackForest.map((url, i) => `--model${i+1} "${url}"`).join(" ");
382
+ report += "```\npython merge_flux_lora.py " + modelArgs + " --output merged_black_forest.safetensors --base-model-path flux_black_forest\n```\n\n";
 
 
 
383
 
384
+ report += "Após a fusão, cada trigger específico chamará o personagem respectivo:\n\n";
385
+ blackForest.forEach(url => {
386
+ const match = url.match(/character\d+|char\d+|style\d+/i);
387
+ const trigger = match ? match[0] : "trigger" + Math.floor(Math.random() * 100);
388
+ report += `- Use \`${trigger}\` para ativar características de ${url}\n`;
389
+ });
390
+ report += "\n";
391
  }
392
 
393
  return report;
 
441
  return html;
442
  }
443
 
444
+ // Carregue o exemplo 2 por padrão ao iniciar
445
  window.onload = function() {
446
+ loadExample(2);
447
  }
448
  </script>
449
  </body>