Spaces:
Running
Running
fix: populate Model Information for custom GGUF models
Browse files- Add custom_model_metadata Gradio State to store actual repo_id, filename, size_mb
- Modify get_model_info() to accept custom_metadata parameter
- Handle custom_hf models with actual metadata instead of placeholder None values
- Update load_custom_model_selected() to return metadata dict on success
- Update event handlers to pass and receive custom_model_metadata
- Model Information now shows correct repo, filename, quantization, size for custom models
app.py
CHANGED
|
@@ -901,16 +901,51 @@ def calculate_effective_max_tokens(model_key: str, max_tokens: int, enable_reaso
|
|
| 901 |
return max_tokens
|
| 902 |
|
| 903 |
|
| 904 |
-
def get_model_info(model_key: str, n_threads: int = 2) -> Tuple[str, str, float, int]:
|
| 905 |
"""Get model information and inference settings for UI display.
|
| 906 |
|
| 907 |
Args:
|
| 908 |
model_key: Model identifier from AVAILABLE_MODELS
|
| 909 |
n_threads: Number of CPU threads currently configured
|
|
|
|
| 910 |
|
| 911 |
Returns:
|
| 912 |
Tuple of (info_text, temperature, top_p, top_k)
|
| 913 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 914 |
m = AVAILABLE_MODELS[model_key]
|
| 915 |
usable_ctx = min(m["max_context"], MAX_USABLE_CTX)
|
| 916 |
settings = m["inference_settings"]
|
|
@@ -1654,61 +1689,16 @@ def create_interface():
|
|
| 1654 |
|
| 1655 |
# Hidden state to store loaded custom model
|
| 1656 |
custom_model_state = gr.State(value=None)
|
| 1657 |
-
|
| 1658 |
-
# Model info section (dynamic)
|
| 1659 |
-
with gr.Group():
|
| 1660 |
-
gr.HTML('<div class="section-header"><span class="section-icon">📊</span> Model Information</div>')
|
| 1661 |
-
# Get default thread count for initial display
|
| 1662 |
-
_default_threads = DEFAULT_CUSTOM_THREADS if DEFAULT_CUSTOM_THREADS > 0 else 2
|
| 1663 |
-
info_output = gr.Markdown(
|
| 1664 |
-
value=get_model_info(DEFAULT_MODEL_KEY, n_threads=_default_threads)[0],
|
| 1665 |
-
elem_classes=["stats-grid"]
|
| 1666 |
-
)
|
| 1667 |
-
|
| 1668 |
-
# Right column - Outputs
|
| 1669 |
-
with gr.Column(scale=2):
|
| 1670 |
-
# Thinking Process
|
| 1671 |
-
with gr.Group():
|
| 1672 |
-
gr.HTML('<div class="section-header"><span class="section-icon">🧠</span> Model Thinking Process</div>')
|
| 1673 |
-
thinking_output = gr.Textbox(
|
| 1674 |
-
label="",
|
| 1675 |
-
lines=12,
|
| 1676 |
-
max_lines=20,
|
| 1677 |
-
show_label=False,
|
| 1678 |
-
placeholder="The AI's reasoning process will appear here in real-time...",
|
| 1679 |
-
elem_classes=["thinking-box"]
|
| 1680 |
-
)
|
| 1681 |
-
|
| 1682 |
-
# Summary Output
|
| 1683 |
-
with gr.Group():
|
| 1684 |
-
gr.HTML('<div class="section-header"><span class="section-icon">📝</span> Final Summary</div>')
|
| 1685 |
-
summary_output = gr.Markdown(
|
| 1686 |
-
value="*Your summarized content will appear here...*",
|
| 1687 |
-
elem_classes=["summary-box"]
|
| 1688 |
-
)
|
| 1689 |
|
| 1690 |
-
#
|
| 1691 |
-
|
| 1692 |
-
|
| 1693 |
-
|
| 1694 |
-
|
| 1695 |
-
|
| 1696 |
-
|
| 1697 |
-
download_output = gr.File(label="Download JSON", visible=True)
|
| 1698 |
-
|
| 1699 |
-
# Debug: System Prompt display
|
| 1700 |
-
with gr.Accordion("🐛 Debug: System Prompt", open=False):
|
| 1701 |
-
system_prompt_debug = gr.Textbox(
|
| 1702 |
-
label="System Prompt (Read-Only)",
|
| 1703 |
-
lines=5,
|
| 1704 |
-
max_lines=10,
|
| 1705 |
-
interactive=False,
|
| 1706 |
-
value="Select a model and click 'Generate Summary' to see the system prompt.",
|
| 1707 |
-
info="This shows the exact system prompt sent to the LLM"
|
| 1708 |
-
)
|
| 1709 |
-
|
| 1710 |
# Function to update settings when model changes
|
| 1711 |
-
def update_settings_on_model_change(model_key, thread_config, custom_threads):
|
| 1712 |
"""Update all Advanced Settings when model selection changes."""
|
| 1713 |
# Calculate n_threads based on preset
|
| 1714 |
thread_preset_map = {
|
|
@@ -1718,7 +1708,7 @@ def create_interface():
|
|
| 1718 |
}
|
| 1719 |
n_threads = thread_preset_map.get(thread_config, 2)
|
| 1720 |
|
| 1721 |
-
info_text, temp_str, top_p_val, top_k_val = get_model_info(model_key, n_threads=n_threads)
|
| 1722 |
temperature = float(temp_str) if temp_str else 0.6
|
| 1723 |
return temperature, top_p_val, top_k_val, info_text
|
| 1724 |
|
|
@@ -1733,7 +1723,7 @@ def create_interface():
|
|
| 1733 |
# Update settings when model changes
|
| 1734 |
model_dropdown.change(
|
| 1735 |
fn=update_settings_on_model_change,
|
| 1736 |
-
inputs=[model_dropdown, thread_config_dropdown, custom_threads_slider],
|
| 1737 |
outputs=[temperature_slider, top_p, top_k, info_output]
|
| 1738 |
)
|
| 1739 |
|
|
@@ -1927,16 +1917,23 @@ def create_interface():
|
|
| 1927 |
def load_custom_model_selected(repo_id, selected_file_display, files_data):
|
| 1928 |
"""Load the selected custom model."""
|
| 1929 |
if not repo_id or not selected_file_display:
|
| 1930 |
-
return "❌ Please enter a Repo ID and select a file first", gr.update(visible=False), None
|
| 1931 |
|
| 1932 |
# Extract filename from the display string
|
| 1933 |
# Format: "📄 filename | size | quant | params | downloads"
|
| 1934 |
filename = selected_file_display.split(" | ")[0].replace("📄 ", "").strip()
|
| 1935 |
|
| 1936 |
if not filename:
|
| 1937 |
-
return "❌ Could not parse filename from selection", gr.update(visible=False), None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1938 |
|
| 1939 |
-
yield "⏳ Loading model... (this may take a while for large files)", gr.update(visible=False), None
|
| 1940 |
|
| 1941 |
try:
|
| 1942 |
# Load the model
|
|
@@ -1945,27 +1942,31 @@ def create_interface():
|
|
| 1945 |
|
| 1946 |
if llm is None:
|
| 1947 |
# Load failed - show error and retry button
|
| 1948 |
-
yield f"❌ {load_msg}", gr.update(visible=True), None
|
| 1949 |
else:
|
| 1950 |
-
# Success
|
| 1951 |
-
|
| 1952 |
-
|
| 1953 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1954 |
|
| 1955 |
except Exception as e:
|
| 1956 |
-
yield f"
|
| 1957 |
|
| 1958 |
load_btn.click(
|
| 1959 |
fn=load_custom_model_selected,
|
| 1960 |
inputs=[model_search_input, custom_file_dropdown, custom_repo_files],
|
| 1961 |
-
outputs=[custom_status, retry_btn, custom_model_state],
|
| 1962 |
)
|
| 1963 |
|
| 1964 |
# Retry button - same as load
|
| 1965 |
retry_btn.click(
|
| 1966 |
fn=load_custom_model_selected,
|
| 1967 |
inputs=[model_search_input, custom_file_dropdown, custom_repo_files],
|
| 1968 |
-
outputs=[custom_status, retry_btn, custom_model_state],
|
| 1969 |
)
|
| 1970 |
|
| 1971 |
# Also update submit button to use custom model state
|
|
|
|
| 901 |
return max_tokens
|
| 902 |
|
| 903 |
|
| 904 |
+
def get_model_info(model_key: str, n_threads: int = 2, custom_metadata: dict = None) -> Tuple[str, str, float, int]:
|
| 905 |
"""Get model information and inference settings for UI display.
|
| 906 |
|
| 907 |
Args:
|
| 908 |
model_key: Model identifier from AVAILABLE_MODELS
|
| 909 |
n_threads: Number of CPU threads currently configured
|
| 910 |
+
custom_metadata: Optional dict with repo_id, filename, size_mb for custom models
|
| 911 |
|
| 912 |
Returns:
|
| 913 |
Tuple of (info_text, temperature, top_p, top_k)
|
| 914 |
"""
|
| 915 |
+
|
| 916 |
+
# Handle custom_hf models with actual metadata
|
| 917 |
+
if model_key == "custom_hf" and custom_metadata and custom_metadata.get("repo_id"):
|
| 918 |
+
m = AVAILABLE_MODELS[model_key]
|
| 919 |
+
repo_id = custom_metadata.get("repo_id", "Not selected")
|
| 920 |
+
filename = custom_metadata.get("filename", "Not selected")
|
| 921 |
+
size_mb = custom_metadata.get("size_mb", 0)
|
| 922 |
+
|
| 923 |
+
# Parse quantization from filename
|
| 924 |
+
quant = parse_quantization(filename) if filename and filename != "Not selected" else "Unknown"
|
| 925 |
+
|
| 926 |
+
info_text = (
|
| 927 |
+
f"## 🤖 {m['name']}\n\n"
|
| 928 |
+
f"### 📊 Model Metadata\n"
|
| 929 |
+
f"| Property | Value |\n"
|
| 930 |
+
f"|----------|-------|\n"
|
| 931 |
+
f"| **Repository** | `{repo_id}` |\n"
|
| 932 |
+
f"| **GGUF File** | `{filename}` |\n"
|
| 933 |
+
f"| **Quantization** | `{quant}` |\n"
|
| 934 |
+
f"| **File Size** | {size_mb:.1f} MB |\n"
|
| 935 |
+
f"| **Context** | {m['max_context']:,} tokens |\n"
|
| 936 |
+
f"| **CPU Threads** | {n_threads} |\n\n"
|
| 937 |
+
f"### ⚙️ Inference Settings\n"
|
| 938 |
+
f"| Property | Value |\n"
|
| 939 |
+
f"|----------|-------|\n"
|
| 940 |
+
f"| **Temperature** | {m['inference_settings']['temperature']} |\n"
|
| 941 |
+
f"| **Top P** | {m['inference_settings']['top_p']} |\n"
|
| 942 |
+
f"| **Top K** | {m['inference_settings']['top_k']} |\n"
|
| 943 |
+
f"| **Repeat Penalty** | {m['inference_settings'].get('repeat_penalty', 1.0)} |\n\n"
|
| 944 |
+
f"⚠️ **Note**: Custom models use conservative defaults (CPU-only, smaller context)."
|
| 945 |
+
)
|
| 946 |
+
return info_text, str(m['inference_settings']["temperature"]), m['inference_settings']["top_p"], m['inference_settings']["top_k"]
|
| 947 |
+
|
| 948 |
+
# Standard predefined models
|
| 949 |
m = AVAILABLE_MODELS[model_key]
|
| 950 |
usable_ctx = min(m["max_context"], MAX_USABLE_CTX)
|
| 951 |
settings = m["inference_settings"]
|
|
|
|
| 1689 |
|
| 1690 |
# Hidden state to store loaded custom model
|
| 1691 |
custom_model_state = gr.State(value=None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1692 |
|
| 1693 |
+
# Hidden state to store custom model metadata (repo_id, filename, size)
|
| 1694 |
+
custom_model_metadata = gr.State(value={
|
| 1695 |
+
"repo_id": None,
|
| 1696 |
+
"filename": None,
|
| 1697 |
+
"size_mb": 0,
|
| 1698 |
+
})
|
| 1699 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1700 |
# Function to update settings when model changes
|
| 1701 |
+
def update_settings_on_model_change(model_key, thread_config, custom_threads, custom_metadata):
|
| 1702 |
"""Update all Advanced Settings when model selection changes."""
|
| 1703 |
# Calculate n_threads based on preset
|
| 1704 |
thread_preset_map = {
|
|
|
|
| 1708 |
}
|
| 1709 |
n_threads = thread_preset_map.get(thread_config, 2)
|
| 1710 |
|
| 1711 |
+
info_text, temp_str, top_p_val, top_k_val = get_model_info(model_key, n_threads=n_threads, custom_metadata=custom_metadata)
|
| 1712 |
temperature = float(temp_str) if temp_str else 0.6
|
| 1713 |
return temperature, top_p_val, top_k_val, info_text
|
| 1714 |
|
|
|
|
| 1723 |
# Update settings when model changes
|
| 1724 |
model_dropdown.change(
|
| 1725 |
fn=update_settings_on_model_change,
|
| 1726 |
+
inputs=[model_dropdown, thread_config_dropdown, custom_threads_slider, custom_model_metadata],
|
| 1727 |
outputs=[temperature_slider, top_p, top_k, info_output]
|
| 1728 |
)
|
| 1729 |
|
|
|
|
| 1917 |
def load_custom_model_selected(repo_id, selected_file_display, files_data):
|
| 1918 |
"""Load the selected custom model."""
|
| 1919 |
if not repo_id or not selected_file_display:
|
| 1920 |
+
return "❌ Please enter a Repo ID and select a file first", gr.update(visible=False), None, {}
|
| 1921 |
|
| 1922 |
# Extract filename from the display string
|
| 1923 |
# Format: "📄 filename | size | quant | params | downloads"
|
| 1924 |
filename = selected_file_display.split(" | ")[0].replace("📄 ", "").strip()
|
| 1925 |
|
| 1926 |
if not filename:
|
| 1927 |
+
return "❌ Could not parse filename from selection", gr.update(visible=False), None, {}
|
| 1928 |
+
|
| 1929 |
+
# Extract size from files_data
|
| 1930 |
+
size_mb = 0
|
| 1931 |
+
for f in files_data:
|
| 1932 |
+
if f["name"] == filename:
|
| 1933 |
+
size_mb = f.get("size_mb", 0)
|
| 1934 |
+
break
|
| 1935 |
|
| 1936 |
+
yield "⏳ Loading model... (this may take a while for large files)", gr.update(visible=False), None, {}
|
| 1937 |
|
| 1938 |
try:
|
| 1939 |
# Load the model
|
|
|
|
| 1942 |
|
| 1943 |
if llm is None:
|
| 1944 |
# Load failed - show error and retry button
|
| 1945 |
+
yield f"❌ {load_msg}", gr.update(visible=True), None, {}
|
| 1946 |
else:
|
| 1947 |
+
# Success - create metadata dict
|
| 1948 |
+
metadata = {
|
| 1949 |
+
"repo_id": repo_id,
|
| 1950 |
+
"filename": filename,
|
| 1951 |
+
"size_mb": size_mb,
|
| 1952 |
+
}
|
| 1953 |
+
size_info = f" ({size_mb:.1f} MB)" if size_mb else ""
|
| 1954 |
+
yield f"✅ Model loaded successfully{size_info}! Ready to generate summaries.", gr.update(visible=False), llm, metadata
|
| 1955 |
|
| 1956 |
except Exception as e:
|
| 1957 |
+
yield f"��� Error loading model: {str(e)}", gr.update(visible=True), None, {}
|
| 1958 |
|
| 1959 |
load_btn.click(
|
| 1960 |
fn=load_custom_model_selected,
|
| 1961 |
inputs=[model_search_input, custom_file_dropdown, custom_repo_files],
|
| 1962 |
+
outputs=[custom_status, retry_btn, custom_model_state, custom_model_metadata],
|
| 1963 |
)
|
| 1964 |
|
| 1965 |
# Retry button - same as load
|
| 1966 |
retry_btn.click(
|
| 1967 |
fn=load_custom_model_selected,
|
| 1968 |
inputs=[model_search_input, custom_file_dropdown, custom_repo_files],
|
| 1969 |
+
outputs=[custom_status, retry_btn, custom_model_state, custom_model_metadata],
|
| 1970 |
)
|
| 1971 |
|
| 1972 |
# Also update submit button to use custom model state
|