guicybercode's picture
Upload app.py
562df32 verified
Raw History Blame Contribute Delete
5.18 kB
import spaces
@spaces.GPU
def _zerogpu_noop():
# ZeroGPU exige uma função decorada; o app roda todo em CPU.
return None
"""Explorador estático do piloto de injeção de prompt (resultados agregados).
Os números vêm de dados/*.csv, copiados de results/SUMMARY.md do pacote
llm-injection-pilot, lidos como texto. Nada é recalculado aqui. Só mudam o
separador decimal (ponto para vírgula) e o formato do intervalo.
"""
from pathlib import Path
import gradio as gr
import pandas as pd
DADOS = Path(__file__).parent / "dados"
def _ler(nome):
return pd.read_csv(DADOS / nome, dtype=str, keep_default_na=False)
def _virgula(s):
return str(s).replace(".", ",")
def _ic(s):
# "[70.9, 92.9]" vira "70,9 a 92,9"
return _virgula(s.strip("[]").replace(", ", " a "))
def tabela_principal(arquivo, n_rotulo):
d = _ler(arquivo)
return pd.DataFrame(
{
"Modelo": d["cfg"],
"Condição do prompt de sistema": d["condition"].map(
{"baseline": "padrão", "hardened": "reforçado"}
),
"Sucessos": d["k"] + " de " + d["n"],
"ASR (%)": d["asr_%"].map(_virgula),
"IC 95% Wilson (%)": d["ic95"].map(_ic),
}
).rename(columns={"Sucessos": n_rotulo})
def tabela_t0():
return tabela_principal("ic_t0.csv", "Sucessos (40 ataques)")
def tabela_t07():
return tabela_principal("ic_t07.csv", "Sucessos (120 gerações)")
def tabela_criterios(temp="0"):
d = _ler("asr_por_categoria.csv")
d = d[d["temp"] == temp]
return pd.DataFrame(
{
"Modelo": d["cfg"],
"Condição": d["condition"].map({"baseline": "padrão", "hardened": "reforçado"}),
"Categoria": d["category"].map({"direct": "direto", "indirect": "indireto"}),
"n": d["n"],
"Critério principal, casamento normalizado (%)": d["asr_principal"].map(_virgula),
"String exata (%)": d["asr_exact_str"].map(_virgula),
}
).reset_index(drop=True)
def filtrar_criterios(temp, modelo):
t = tabela_criterios("0" if temp == "T=0" else "0.7")
if modelo != "Todos":
t = t[t["Modelo"] == modelo]
return t.reset_index(drop=True)
MODELOS = ["Todos"] + sorted(_ler("ic_t0.csv")["cfg"].unique().tolist())
TEXTO_TOPO = """
# Piloto de injeção de prompt em dois modelos pequenos (CPU): resultados agregados
Este Space mostra só números agregados de um piloto pequeno e exploratório. Os ataques
e os textos dos prompts de ataque não são exibidos aqui.
"""
TEXTO_T0 = """
## Número principal: temperatura 0 (decodificação gulosa)
ASR é a taxa de ataque bem-sucedido, pelo critério principal (casamento normalizado),
sobre os 40 ataques por modelo e condição (16 diretos e 24 indiretos). Os dois modelos
não se comparam entre si.
"""
TEXTO_T07 = """
## Confirmação: temperatura 0,7 (3 seeds)
São 120 gerações por modelo e condição, que correspondem aos mesmos 40 ataques repetidos
em 3 seeds. As gerações não são independentes, então os intervalos abaixo ficam otimistas.
Use esta tabela como confirmação do T=0, não como número principal.
"""
TEXTO_CRITERIO = """
## Critério principal ao lado da string exata
O critério de sucesso foi corrigido depois de eu ver os resultados. A coluna de string
exata é o critério original e fica ao lado para a diferença ficar visível. Valores em
porcentagem, por categoria, como estão em results/SUMMARY.md.
"""
TEXTO_RESSALVAS = """
## Ressalvas
- Piloto pequeno e exploratório: 40 ataques por modelo e condição.
- Os ataques são próprios, escritos para este piloto. Não são um benchmark publicado.
- O critério de sucesso foi corrigido depois de ver os resultados. A string exata original
está na tabela de critérios.
- Os dois modelos não se comparam entre si: tamanho e quantização diferentes (1,7B em Q8_0
contra 3B em Q4_K_M) e amostra pequena.
- Reforçar o prompt de sistema não mudou o total em T=0 nos dois modelos. Com esta amostra
não há diferença detectável, e isso não quer dizer que o reforço não funcione.
- Não é réplica do INFUSE e não se compara com os números dele: benchmark, juiz e modelos
são outros.
- Execução em CPU, modo sem raciocínio (/no_think), 256 tokens no máximo por resposta.
- Nenhuma conclusão sobre a segurança de modelo algum.
"""
with gr.Blocks(title="Piloto de injeção de prompt: explorador") as demo:
gr.Markdown(TEXTO_TOPO)
gr.Markdown(TEXTO_T0)
gr.Dataframe(value=tabela_t0(), interactive=False, wrap=True)
gr.Markdown(TEXTO_T07)
gr.Dataframe(value=tabela_t07(), interactive=False, wrap=True)
gr.Markdown(TEXTO_CRITERIO)
with gr.Row():
sel_t = gr.Radio(["T=0", "T=0,7"], value="T=0", label="Temperatura")
sel_m = gr.Dropdown(MODELOS, value="Todos", label="Modelo")
saida = gr.Dataframe(value=filtrar_criterios("T=0", "Todos"), interactive=False, wrap=True)
sel_t.change(filtrar_criterios, [sel_t, sel_m], saida)
sel_m.change(filtrar_criterios, [sel_t, sel_m], saida)
gr.Markdown(TEXTO_RESSALVAS)
if __name__ == "__main__":
demo.launch()