openTARS / app /tars_mais_modelos.py
ProjectOpenTARS4's picture
Mirror of openTARS 5.2 Ranger (revision 2026110101)
2695555 verified
Raw History Blame Contribute Delete
9.13 kB
"""openTARS: a lista da p谩gina "Mais modelos" (Configura莽玫es). S贸 dados e contas simples, sem Qt, para testar 脿 parte.
Nomes e tamanhos conferidos nas p谩ginas do ollama.com em 21/10/2026 (s贸 entra o que a p谩gina mostra com um tamanho 煤nico; gemma4 e
qwen3.5 ficaram de fora porque a p谩gina d谩 uma faixa de tamanhos). S贸 entram o Bonsai 2 oficial (Prism ML), os modelos de
imagem do namespace x/ (experimental, do Ollama) e a biblioteca principal. Vers玫es da comunidade ficam de fora de prop贸sito (origem desconhecida e algumas "sem filtro").
Se um tamanho mudar l谩, 茅 aqui que se corrige.
"""
# (id do grupo, ((tag no Ollama, nome mostrado, tamanho do download em GB, o que sabe fazer), ...))
GRUPOS = (
# 25/10 (decis茫o do Enzo): os modelos do openTARS no topo, o Lite primeiro e destacado (茅 o que fica em segundo plano)
("opentars", (
("ProjectOpenTARS/Gargantua-2:lite", "Gargantua 2 Lite", 0.617, ("vision", "tools")),
("ProjectOpenTARS/Gargantua-2:latest", "Gargantua 2", 1.6, ("vision", "tools")),
("ProjectOpenTARS/Gargantua:code", "Gargantua Code", 1.1, ("tools",)),
)),
("bonsai", (
("bonsai-2:2b", "Bonsai 2 路 2B", 0.911, ("vision", "tools", "thinking")),
("bonsai-2:4b", "Bonsai 2 路 4B", 1.6, ("vision", "tools", "thinking")),
("bonsai-2:9b", "Bonsai 2 路 9B", 3.2, ("vision", "tools", "thinking")),
("bonsai-2:27b", "Bonsai 2 路 27B", 8.3, ("vision", "tools", "thinking")),
)),
# A biblioteca oficial do Ollama s贸 tem estas duas fam铆lias de imagem (namespace x/, experimental); o que muda
# entre as linhas 茅 o tamanho e a precis茫o dos pesos (fp4 茅 o padr茫o, fp8 e bf16 pesam mais).
("imagem", (
("x/flux2-klein:4b", "FLUX.2 klein 路 4B", 5.7, ("image",)),
("x/flux2-klein:4b-fp8", "FLUX.2 klein 路 4B fp8", 9.5, ("image",)),
("x/flux2-klein:4b-bf16", "FLUX.2 klein 路 4B bf16", 16.0, ("image",)),
("x/flux2-klein:9b", "FLUX.2 klein 路 9B", 12.0, ("image",)),
("x/flux2-klein:9b-fp8", "FLUX.2 klein 路 9B fp8", 20.0, ("image",)),
("x/flux2-klein:9b-bf16", "FLUX.2 klein 路 9B bf16", 35.0, ("image",)),
("x/z-image-turbo", "Z-Image Turbo 路 6B", 13.0, ("image",)),
("x/z-image-turbo:bf16", "Z-Image Turbo 路 6B bf16", 33.0, ("image",)),
)),
("geral", (
("tinyllama:1.1b", "TinyLlama 路 1.1B", 0.638, ("text",)),
("qwen2.5:0.5b", "Qwen2.5 路 0.5B", 0.398, ("tools",)),
("qwen3:0.6b", "Qwen3 路 0.6B", 0.523, ("tools", "thinking")),
("gemma3:1b", "Gemma 3 路 1B", 0.806, ("text",)),
("qwen2.5:1.5b", "Qwen2.5 路 1.5B", 0.986, ("tools",)),
("deepseek-r1:1.5b", "DeepSeek-R1 路 1.5B", 1.1, ("tools", "thinking")),
("qwen3:1.7b", "Qwen3 路 1.7B", 1.4, ("tools", "thinking")),
("gemma2:2b", "Gemma 2 路 2B", 1.6, ("text",)),
("qwen2.5:3b", "Qwen2.5 路 3B", 1.9, ("tools",)),
("llama3.2:3b", "Llama 3.2 路 3B", 2.0, ("tools",)),
("phi3:3.8b", "Phi-3 路 3.8B", 2.2, ("text",)),
("qwen3:4b", "Qwen3 路 4B", 2.5, ("tools", "thinking")),
("mistral:7b", "Mistral 路 7B", 4.4, ("tools",)),
("qwen2.5:7b", "Qwen2.5 路 7B", 4.7, ("tools",)),
("deepseek-r1:7b", "DeepSeek-R1 路 7B", 4.7, ("tools", "thinking")),
("llama3.1:8b", "Llama 3.1 路 8B", 4.9, ("tools",)),
("qwen3:8b", "Qwen3 路 8B", 5.2, ("tools", "thinking")),
("deepseek-r1:8b", "DeepSeek-R1 路 8B", 5.2, ("tools", "thinking")),
("gemma2:9b", "Gemma 2 路 9B", 5.4, ("text",)),
("mistral-nemo:12b", "Mistral Nemo 路 12B", 7.1, ("tools",)),
("phi3:14b", "Phi-3 medium 路 14B", 7.9, ("text",)),
("qwen2.5:14b", "Qwen2.5 路 14B", 9.0, ("tools",)),
("deepseek-r1:14b", "DeepSeek-R1 路 14B", 9.0, ("tools", "thinking")),
("phi4:14b", "Phi-4 路 14B", 9.1, ("text",)),
("qwen3:14b", "Qwen3 路 14B", 9.3, ("tools", "thinking")),
)),
("visao", (
("qwen3-vl:2b", "Qwen3-VL 路 2B", 1.9, ("vision", "tools", "thinking")),
("qwen3-vl:4b", "Qwen3-VL 路 4B", 3.3, ("vision", "tools", "thinking")),
("gemma3:4b", "Gemma 3 路 4B", 3.4, ("vision",)),
("llava:7b", "LLaVA 路 7B", 4.7, ("vision",)),
("qwen3-vl:8b", "Qwen3-VL 路 8B", 6.2, ("vision", "tools", "thinking")),
("llava:13b", "LLaVA 路 13B", 8.0, ("vision",)),
("gemma3:12b", "Gemma 3 路 12B", 8.2, ("vision",)),
)),
("codigo", (
("qwen2.5-coder:1.5b", "Qwen2.5-Coder 路 1.5B", 0.986, ("tools",)),
("qwen2.5-coder:3b", "Qwen2.5-Coder 路 3B", 1.9, ("tools",)),
("qwen2.5-coder:7b", "Qwen2.5-Coder 路 7B", 4.7, ("tools",)),
("qwen2.5-coder:14b", "Qwen2.5-Coder 路 14B", 9.0, ("tools",)),
("qwen2.5-coder:32b", "Qwen2.5-Coder 路 32B", 20.0, ("tools",)),
("qwen3-coder:30b", "Qwen3-Coder 路 30B", 19.0, ("tools",)),
)),
# Pedem uma placa de v铆deo grande ou muita mem贸ria (a RTX 3050 de 6 GB do Enzo n茫o os roda bem).
("grandes", (
("gpt-oss:20b", "gpt-oss 路 20B", 14.0, ("tools", "thinking")),
("gemma2:27b", "Gemma 2 路 27B", 16.0, ("text",)),
("gemma3:27b", "Gemma 3 路 27B", 17.0, ("vision",)),
("qwen3:30b", "Qwen3 路 30B", 19.0, ("tools", "thinking")),
("qwen3:32b", "Qwen3 路 32B", 20.0, ("tools", "thinking")),
("qwen2.5:32b", "Qwen2.5 路 32B", 20.0, ("tools",)),
("deepseek-r1:32b", "DeepSeek-R1 路 32B", 20.0, ("tools", "thinking")),
("llava:34b", "LLaVA 路 34B", 20.0, ("vision",)),
)),
)
CAPACIDADES = ("vision", "tools", "thinking", "image", "text")
DESTAQUE = "ProjectOpenTARS/Gargantua-2:lite"
# Etiquetas que o Ollama mostra com outro nome quando o modelo foi baixado sem a tag (o mesmo arquivo).
_APELIDOS = {
"bonsai-2:9b": "bonsai-2:latest",
"gemma3:4b": "gemma3:latest",
"gemma2:9b": "gemma2:latest",
"llama3.2:3b": "llama3.2:latest",
"llama3.1:8b": "llama3.1:latest",
"qwen3:8b": "qwen3:latest",
"qwen3-vl:8b": "qwen3-vl:latest",
"qwen3-coder:30b": "qwen3-coder:latest",
"qwen2.5:7b": "qwen2.5:latest",
"qwen2.5-coder:7b": "qwen2.5-coder:latest",
"deepseek-r1:8b": "deepseek-r1:latest",
"mistral:7b": "mistral:latest",
"mistral-nemo:12b": "mistral-nemo:latest",
"llava:7b": "llava:latest",
"phi3:3.8b": "phi3:latest",
"phi4:14b": "phi4:latest",
"gpt-oss:20b": "gpt-oss:latest",
"tinyllama:1.1b": "tinyllama:latest",
"x/flux2-klein:4b": "x/flux2-klein:latest",
"x/z-image-turbo": "x/z-image-turbo:latest",
}
def todas_as_tags():
return [item[0] for _, itens in GRUPOS for item in itens]
def _norma(tag):
tag = tag.strip().lower()
return tag if ":" in tag else tag + ":latest"
def instalado(tag, instalados):
"""O modelo `tag` j谩 est谩 entre os `instalados` (lista de nomes do /api/tags)?"""
nomes = {_norma(n) for n in instalados}
return _norma(tag) in nomes or _norma(_APELIDOS.get(tag, tag)) in nomes
def tamanho_texto(gb):
return f"{round(gb * 1000)} MB" if gb < 1 else f"{gb:.1f} GB"
def espaco_necessario(gb):
"""O download mais 10% e 1 GB de folga (o Ollama descompacta e guarda camadas por cima)."""
return gb * 1.1 + 1.0
def cabe(gb, livre_gb):
"""Cabe no disco? Sem saber o espa莽o livre (None), deixa tentar: o Ollama avisa se faltar."""
return livre_gb is None or livre_gb >= espaco_necessario(gb)
# 26/10 (pedido do Enzo): os modelos que combinam com o computador
GRUPOS_RECOMENDADOS = ("geral", "visao", "codigo") # um recomendado por grupo
def hardware(vram_gb=None, ram_gb=None):
"""{'vram_gb': placa dedicada (0 se n茫o h谩), 'ram_gb': mem贸ria}. Sem argumentos, l锚 o computador."""
if vram_gb is None:
try:
import tars_primeiro_uso as pu
vram_gb = pu._vram_mb() / 1024
except Exception: # noqa: BLE001
vram_gb = 0.0
if ram_gb is None:
try:
import psutil
ram_gb = psutil.virtual_memory().total / 2 ** 30
except Exception: # noqa: BLE001
ram_gb = 8.0
return {"vram_gb": vram_gb if vram_gb >= 2.0 else 0.0, "ram_gb": ram_gb} # menos de 2 GB 茅 v铆deo integrado
def avaliar(gb, hw):
"""'otimo' (cabe na placa com folga, ou 茅 pequeno o bastante para o processador), 'ok' (roda, mais devagar) ou 'pesado'.
O tamanho do download aproxima a mem贸ria usada (j谩 vem quantizado)."""
if hw["vram_gb"]:
if gb <= hw["vram_gb"] * 0.8:
return "otimo"
elif gb <= min(hw["ram_gb"] * 0.3, 5.0):
return "otimo"
return "ok" if gb <= hw["ram_gb"] * 0.5 else "pesado"
def recomendados(hw):
"""Em cada grupo, o maior modelo 'otimo', preferindo os que usam ferramentas e, no empate, os sem racioc铆nio longo."""
achados = []
for grupo, itens in GRUPOS:
cabem = [i for i in itens if grupo in GRUPOS_RECOMENDADOS and avaliar(i[2], hw) == "otimo"]
if cabem:
achados.append(max(cabem, key=lambda i: ("tools" in i[3], i[2], "thinking" not in i[3]))[0])
return achados