Luigi commited on
Commit
447632e
·
1 Parent(s): b8f8edc

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

Files changed (1) hide show
  1. app.py +68 -67
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
- # Action buttons for outputs
1691
- with gr.Row():
1692
- copy_summary_btn = gr.Button("📋 Copy Summary", size="sm")
1693
- copy_thinking_btn = gr.Button("📋 Copy Thinking", size="sm")
1694
- download_btn = gr.Button("⬇️ Download (JSON)", size="sm")
1695
-
1696
- # File output component for download
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
- model_info = next((f for f in files_data if f["name"] == filename), {})
1952
- size_info = f" ({model_info.get('size_mb', 'Unknown')} MB)" if model_info else ""
1953
- yield f"✅ Model loaded successfully{size_info}! Ready to generate summaries.", gr.update(visible=False), llm
 
 
 
 
1954
 
1955
  except Exception as e:
1956
- yield f" Error loading model: {str(e)}", gr.update(visible=True), None
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