Spaces:
Sleeping
Sleeping
File size: 6,227 Bytes
86ce226 6c7eb2d 86ce226 07a26be 86d72db 86ce226 c726fcf 86ce226 6c7eb2d 86ce226 21673e2 6c7eb2d 86ce226 6c7eb2d 86ce226 50f6a03 21673e2 50f6a03 6c7eb2d 86ce226 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import gradio as gr
import requests
from PIL import Image
import io
from typing import Any, Tuple
import os
class Client:
def __init__(self, server_url: str):
self.server_url = server_url
def send_request(self, task_name: str, model_name: str, text: str, normalization_type: str) -> Tuple[Any, str]:
response = requests.post(
self.server_url,
json={
"task_name": task_name,
"model_name": model_name,
"text": text,
"normalization_type": normalization_type
},
timeout=60
)
if response.status_code == 200:
response_data = response.json()
img_data = bytes.fromhex(response_data["image"])
img = Image.open(io.BytesIO(img_data))
return img, "OK"
else:
return "Error, please retry", "Error: Could not get response from server"
client = Client(f"http://{os.environ['SERVER']}/predict")
def get_layerwise_nonlinearity(task_name: str, model_name: str, text: str, normalization_type: str) -> Tuple[Any, str]:
return client.send_request(task_name, model_name, text, normalization_type)
def update_output(task_name: str, model_name: str, text: str, normalization_type: str) -> Tuple[Any]:
img, _ = get_layerwise_nonlinearity(task_name, model_name, text, normalization_type)
return img
def set_default(task_name: str) -> str:
if task_name in ["Layer wise non-linearity", "Next-token prediction from intermediate representations", "Tokenwise loss without i-th layer"]:
return "token-wise"
return "global"
def check_normalization(task_name: str, normalization_name) -> Tuple[str]:
if task_name == "Contextualization measurement" and normalization_name == "token-wise":
return "global"
return normalization_name
def update_description(task_name: str) -> str:
descriptions = {
"Layer wise non-linearity": "Non-linearity per layer: shows how complex each layer's transformation is. Red = more nonlinear.",
"Next-token prediction from intermediate representations": "Layerwise token prediction: when does the model start guessing correctly?",
"Contextualization measurement": "Context stored in each token: how well can the model reconstruct the previous context?",
"Layerwise predictions (logit lens)": "Logit lens: what does each layer believe the next token should be?",
"Tokenwise loss without i-th layer": "Layer ablation: how much does performance drop if a layer is removed?"
}
return descriptions.get(task_name, "ℹ️ No description available.")
with gr.Blocks() as demo:
# gr.Markdown("# 🔬 LLM-Microscope — Understanding Token Representations in Transformers")
gr.Markdown("# 🔬 LLM-Microscope — A Look Inside the Black Box")
gr.Markdown("Select a model, analysis mode, and input — then peek inside the black box of an LLM to see which layers matter most, which tokens carry the most memory, and how predictions evolve.")
with gr.Row():
model_selector = gr.Dropdown(
choices=[
"facebook/opt-1.3b",
"TheBloke/Llama-2-7B-fp16",
"Qwen/Qwen3-8B"
],
value="facebook/opt-1.3b",
label="Select Model"
)
task_selector = gr.Dropdown(
choices=[
"Layer wise non-linearity",
"Next-token prediction from intermediate representations",
"Contextualization measurement",
"Layerwise predictions (logit lens)",
"Tokenwise loss without i-th layer"
],
value="Layer wise non-linearity",
label="Select Mode"
)
normalization_selector = gr.Dropdown(
choices=["global", "token-wise"],
value="token-wise",
label="Select Normalization"
)
task_description = gr.Markdown("ℹ️ Choose a mode to see what it does.")
with gr.Column():
text_message = gr.Textbox(label="Enter your input text:", value="I love to live my life")
submit = gr.Button("Submit")
box_for_plot = gr.Image(label="Visualization", type="pil")
with gr.Accordion("📘 More Info and Explanation", open=False):
gr.Markdown("""
This heatmap shows **how each token is processed** across layers of a language model. Here's how to read it:
- **Rows**: layers of the model (bottom = deeper)
- **Columns**: input tokens
- **Colors**: intensity of effect (depends on the selected metric)
---
### Metrics explained:
- `Layer wise non-linearity`: how nonlinear the transformation is at each layer (red = more nonlinear).
- `Next-token prediction from intermediate representations`: shows which layers begin to make good predictions.
- `Contextualization measurement`: tokens with more context info get lower scores (green = more context).
- `Layerwise predictions (logit lens)`: tracks how the model’s guesses evolve at each layer.
- `Tokenwise loss without i-th layer`: shows how much each token depends on a specific layer. Red means performance drops if we skip this layer.
Use this tool to **peek inside the black box** — it reveals which layers matter most, which tokens carry the most memory, and how LLMs evolve their predictions.
---
You can also use `llm-microscope` as a Python library to run these analyses on **your own models and data**.
Just install it with: `pip install llm-microscope`
More details provided in [GitHub repo](https://github.com/AIRI-Institute/LLM-Microscope).
""")
task_selector.change(fn=update_description, inputs=[task_selector], outputs=[task_description])
task_selector.select(set_default, [task_selector], [normalization_selector])
normalization_selector.select(check_normalization, [task_selector, normalization_selector], [normalization_selector])
submit.click(
fn=update_output,
inputs=[task_selector, model_selector, text_message, normalization_selector],
outputs=[box_for_plot]
)
if __name__ == "__main__":
demo.launch(share=True, server_port=7860, server_name="0.0.0.0")
|