Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import torch
|
| 3 |
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import time
|
| 5 |
import os
|
| 6 |
import json
|
|
@@ -52,38 +58,55 @@ def load_model_in_background():
|
|
| 52 |
global MODEL, TOKENIZER, PIPE, MODEL_LOADING, MODEL_LOADED
|
| 53 |
try:
|
| 54 |
MODEL_LOADING = True
|
| 55 |
-
print("Starting model loading...")
|
| 56 |
|
| 57 |
-
# Model identifier
|
| 58 |
model_id = "mistralai/Mistral-7B-Instruct-v0.3"
|
| 59 |
|
| 60 |
print("Loading tokenizer...")
|
| 61 |
-
|
|
|
|
| 62 |
|
| 63 |
-
print("Loading model
|
|
|
|
| 64 |
MODEL = AutoModelForCausalLM.from_pretrained(
|
| 65 |
model_id,
|
| 66 |
-
torch_dtype=torch.float16,
|
| 67 |
-
device_map="auto",
|
| 68 |
-
low_cpu_mem_usage=True
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
)
|
| 70 |
|
| 71 |
-
print("Creating pipeline...")
|
|
|
|
| 72 |
PIPE = pipeline(
|
| 73 |
"text-generation",
|
| 74 |
model=MODEL,
|
| 75 |
tokenizer=TOKENIZER,
|
| 76 |
-
return_full_text=False
|
|
|
|
| 77 |
)
|
| 78 |
|
|
|
|
| 79 |
MODEL_LOADING = False
|
| 80 |
MODEL_LOADED = True
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
except Exception as e:
|
| 84 |
MODEL_LOADING = False
|
| 85 |
print(f"Error loading model: {str(e)}")
|
| 86 |
-
|
|
|
|
| 87 |
|
| 88 |
# Function to generate response using the model
|
| 89 |
def generate_response(prompt, chat_history, progress=gr.Progress()):
|
|
@@ -533,6 +556,9 @@ def create_gradio_interface():
|
|
| 533 |
with gr.Blocks(css=css) as app:
|
| 534 |
gr.Markdown("# 🤖 Advanced Mistral-7B-Instruct Chatbot for n8n JSON Generation")
|
| 535 |
|
|
|
|
|
|
|
|
|
|
| 536 |
with gr.Tab("Chat"):
|
| 537 |
with gr.Row():
|
| 538 |
with gr.Column(scale=3):
|
|
@@ -554,6 +580,49 @@ def create_gradio_interface():
|
|
| 554 |
)
|
| 555 |
send_btn = gr.Button("Send", scale=1, variant="primary")
|
| 556 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
with gr.Row():
|
| 558 |
chat_selector = gr.Dropdown(
|
| 559 |
choices=get_available_chats(),
|
|
@@ -574,9 +643,20 @@ def create_gradio_interface():
|
|
| 574 |
|
| 575 |
with gr.Column(scale=1):
|
| 576 |
# Model Loading and Settings
|
| 577 |
-
|
|
|
|
|
|
|
|
|
|
| 578 |
model_status = gr.Textbox(label="Model Status", value="Not loaded", interactive=False)
|
| 579 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 580 |
# System Prompt
|
| 581 |
system_prompt_input = gr.Textbox(
|
| 582 |
label="System Prompt",
|
|
@@ -675,6 +755,76 @@ def create_gradio_interface():
|
|
| 675 |
}
|
| 676 |
```
|
| 677 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
## Tips for Creating n8n-Compatible JSON
|
| 679 |
|
| 680 |
1. Ensure all JSON keys and values are properly quoted
|
|
@@ -687,17 +837,24 @@ def create_gradio_interface():
|
|
| 687 |
""")
|
| 688 |
|
| 689 |
# Set up event handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
send_btn.click(
|
| 691 |
-
|
| 692 |
-
inputs=[msg, chatbot],
|
| 693 |
outputs=chatbot,
|
| 694 |
api_name="chat"
|
| 695 |
)
|
| 696 |
|
| 697 |
msg.submit(
|
| 698 |
-
|
| 699 |
-
inputs=[msg, chatbot],
|
| 700 |
-
outputs=chatbot,
|
| 701 |
api_name=False
|
| 702 |
)
|
| 703 |
|
|
@@ -707,6 +864,13 @@ def create_gradio_interface():
|
|
| 707 |
api_name="load_model"
|
| 708 |
)
|
| 709 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
update_prompt_btn.click(
|
| 711 |
update_system_prompt,
|
| 712 |
inputs=system_prompt_input,
|
|
|
|
| 1 |
+
# Required imports - ensure all dependencies are installed
|
| 2 |
import gradio as gr
|
| 3 |
import torch
|
| 4 |
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
|
| 5 |
+
try:
|
| 6 |
+
import bitsandbytes as bnb
|
| 7 |
+
except ImportError:
|
| 8 |
+
print("WARNING: bitsandbytes not installed. Required for 4-bit quantization.")
|
| 9 |
+
|
| 10 |
import time
|
| 11 |
import os
|
| 12 |
import json
|
|
|
|
| 58 |
global MODEL, TOKENIZER, PIPE, MODEL_LOADING, MODEL_LOADED
|
| 59 |
try:
|
| 60 |
MODEL_LOADING = True
|
| 61 |
+
print("Starting model loading process...")
|
| 62 |
|
| 63 |
+
# Model identifier - using quantized 4-bit version for reduced memory
|
| 64 |
model_id = "mistralai/Mistral-7B-Instruct-v0.3"
|
| 65 |
|
| 66 |
print("Loading tokenizer...")
|
| 67 |
+
# Set tokenizer to use legacy format to avoid issues
|
| 68 |
+
TOKENIZER = AutoTokenizer.from_pretrained(model_id, legacy_format=True)
|
| 69 |
|
| 70 |
+
print("Loading model with optimized settings for limited memory...")
|
| 71 |
+
# Configure model loading with 4-bit quantization for minimum memory usage
|
| 72 |
MODEL = AutoModelForCausalLM.from_pretrained(
|
| 73 |
model_id,
|
| 74 |
+
torch_dtype=torch.float16, # Use half precision
|
| 75 |
+
device_map="auto", # Automatically distribute across available GPUs/CPU
|
| 76 |
+
low_cpu_mem_usage=True,
|
| 77 |
+
load_in_4bit=True, # Enable 4-bit quantization
|
| 78 |
+
max_memory={0: "8GiB"}, # Limit memory usage per GPU
|
| 79 |
+
offload_folder="offload_folder", # Use disk offloading if needed
|
| 80 |
+
offload_state_dict=True # Offload state dict to CPU when possible
|
| 81 |
)
|
| 82 |
|
| 83 |
+
print("Creating optimized pipeline...")
|
| 84 |
+
# Create text generation pipeline with more efficient settings
|
| 85 |
PIPE = pipeline(
|
| 86 |
"text-generation",
|
| 87 |
model=MODEL,
|
| 88 |
tokenizer=TOKENIZER,
|
| 89 |
+
return_full_text=False,
|
| 90 |
+
batch_size=1 # Process one batch at a time to reduce memory
|
| 91 |
)
|
| 92 |
|
| 93 |
+
print("Model loading complete!")
|
| 94 |
MODEL_LOADING = False
|
| 95 |
MODEL_LOADED = True
|
| 96 |
+
return "Model loaded successfully! Ready to generate responses."
|
| 97 |
+
except torch.cuda.OutOfMemoryError as e:
|
| 98 |
+
MODEL_LOADING = False
|
| 99 |
+
print(f"CUDA out of memory error: {str(e)}")
|
| 100 |
+
return f"GPU memory error: {str(e)}. Try restarting or using a machine with more GPU memory."
|
| 101 |
+
except ImportError as e:
|
| 102 |
+
MODEL_LOADING = False
|
| 103 |
+
print(f"Import error - missing dependencies: {str(e)}")
|
| 104 |
+
return f"Missing dependencies: {str(e)}. Try 'pip install -U bitsandbytes transformers accelerate'"
|
| 105 |
except Exception as e:
|
| 106 |
MODEL_LOADING = False
|
| 107 |
print(f"Error loading model: {str(e)}")
|
| 108 |
+
error_type = type(e).__name__
|
| 109 |
+
return f"Error loading model ({error_type}): {str(e)}"
|
| 110 |
|
| 111 |
# Function to generate response using the model
|
| 112 |
def generate_response(prompt, chat_history, progress=gr.Progress()):
|
|
|
|
| 556 |
with gr.Blocks(css=css) as app:
|
| 557 |
gr.Markdown("# 🤖 Advanced Mistral-7B-Instruct Chatbot for n8n JSON Generation")
|
| 558 |
|
| 559 |
+
# Add fallback mode when model loading fails
|
| 560 |
+
fallback_mode = gr.State(False)
|
| 561 |
+
|
| 562 |
with gr.Tab("Chat"):
|
| 563 |
with gr.Row():
|
| 564 |
with gr.Column(scale=3):
|
|
|
|
| 580 |
)
|
| 581 |
send_btn = gr.Button("Send", scale=1, variant="primary")
|
| 582 |
|
| 583 |
+
# Fallback response mode when model fails to load
|
| 584 |
+
def simple_fallback_response(message, history):
|
| 585 |
+
# Sample n8n JSON structure for common requests
|
| 586 |
+
if any(keyword in message.lower() for keyword in ['json', 'n8n', 'workflow']):
|
| 587 |
+
response = """Here's a basic n8n workflow JSON structure you can use:
|
| 588 |
+
|
| 589 |
+
```json
|
| 590 |
+
{
|
| 591 |
+
"name": "Simple Workflow",
|
| 592 |
+
"nodes": [
|
| 593 |
+
{
|
| 594 |
+
"parameters": {
|
| 595 |
+
"values": {
|
| 596 |
+
"string": [
|
| 597 |
+
{
|
| 598 |
+
"name": "data",
|
| 599 |
+
"value": "Your data here"
|
| 600 |
+
}
|
| 601 |
+
]
|
| 602 |
+
}
|
| 603 |
+
},
|
| 604 |
+
"id": "1",
|
| 605 |
+
"name": "Set",
|
| 606 |
+
"type": "n8n-nodes-base.set",
|
| 607 |
+
"typeVersion": 1,
|
| 608 |
+
"position": [250, 300]
|
| 609 |
+
}
|
| 610 |
+
],
|
| 611 |
+
"connections": {},
|
| 612 |
+
"active": false,
|
| 613 |
+
"settings": {},
|
| 614 |
+
"version": 1
|
| 615 |
+
}
|
| 616 |
+
```
|
| 617 |
+
|
| 618 |
+
You can customize this template with your specific data. If you need a more complex structure or specific node types, please let me know."""
|
| 619 |
+
elif 'file' in message.lower() or 'data' in message.lower():
|
| 620 |
+
response = "To analyze files or data, please upload your file in the 'File Analysis & JSON Conversion' tab. I'll be able to help you convert it to n8n compatible JSON format."
|
| 621 |
+
else:
|
| 622 |
+
response = "I'm currently operating in fallback mode because the Mistral-7B model couldn't be loaded. I can still help with basic n8n JSON structures. Try asking for a specific workflow type or JSON structure you need for n8n."
|
| 623 |
+
|
| 624 |
+
return history + [(message, response)]
|
| 625 |
+
|
| 626 |
with gr.Row():
|
| 627 |
chat_selector = gr.Dropdown(
|
| 628 |
choices=get_available_chats(),
|
|
|
|
| 643 |
|
| 644 |
with gr.Column(scale=1):
|
| 645 |
# Model Loading and Settings
|
| 646 |
+
with gr.Row():
|
| 647 |
+
load_model_btn = gr.Button("Load Mistral-7B Model", variant="primary")
|
| 648 |
+
use_fallback_btn = gr.Button("Use Simple JSON Mode", variant="secondary")
|
| 649 |
+
|
| 650 |
model_status = gr.Textbox(label="Model Status", value="Not loaded", interactive=False)
|
| 651 |
|
| 652 |
+
# Function to toggle fallback mode
|
| 653 |
+
def toggle_fallback_mode(state):
|
| 654 |
+
global MODEL_LOADED
|
| 655 |
+
if MODEL_LOADED:
|
| 656 |
+
return state, "Model is already loaded. No need for fallback mode."
|
| 657 |
+
else:
|
| 658 |
+
return not state, "Using simple JSON generation mode. Limited functionality but no model loading required."
|
| 659 |
+
|
| 660 |
# System Prompt
|
| 661 |
system_prompt_input = gr.Textbox(
|
| 662 |
label="System Prompt",
|
|
|
|
| 755 |
}
|
| 756 |
```
|
| 757 |
|
| 758 |
+
## Common n8n Node Types
|
| 759 |
+
|
| 760 |
+
### HTTP Request Node
|
| 761 |
+
```json
|
| 762 |
+
{
|
| 763 |
+
"parameters": {
|
| 764 |
+
"url": "https://api.example.com/data",
|
| 765 |
+
"method": "GET",
|
| 766 |
+
"authentication": "none",
|
| 767 |
+
"sendHeaders": true,
|
| 768 |
+
"headerParameters": {
|
| 769 |
+
"parameters": [
|
| 770 |
+
{
|
| 771 |
+
"name": "Content-Type",
|
| 772 |
+
"value": "application/json"
|
| 773 |
+
}
|
| 774 |
+
]
|
| 775 |
+
}
|
| 776 |
+
},
|
| 777 |
+
"name": "HTTP Request",
|
| 778 |
+
"type": "n8n-nodes-base.httpRequest",
|
| 779 |
+
"typeVersion": 1,
|
| 780 |
+
"position": [250, 300],
|
| 781 |
+
"id": "1"
|
| 782 |
+
}
|
| 783 |
+
```
|
| 784 |
+
|
| 785 |
+
### Function Node (JavaScript)
|
| 786 |
+
```json
|
| 787 |
+
{
|
| 788 |
+
"parameters": {
|
| 789 |
+
"functionCode": "// Code here\nreturn items;"
|
| 790 |
+
},
|
| 791 |
+
"name": "Function",
|
| 792 |
+
"type": "n8n-nodes-base.function",
|
| 793 |
+
"typeVersion": 1,
|
| 794 |
+
"position": [450, 300],
|
| 795 |
+
"id": "2"
|
| 796 |
+
}
|
| 797 |
+
```
|
| 798 |
+
|
| 799 |
+
### Set Node (Manual Data)
|
| 800 |
+
```json
|
| 801 |
+
{
|
| 802 |
+
"parameters": {
|
| 803 |
+
"values": {
|
| 804 |
+
"string": [
|
| 805 |
+
{
|
| 806 |
+
"name": "fieldName",
|
| 807 |
+
"value": "value"
|
| 808 |
+
}
|
| 809 |
+
],
|
| 810 |
+
"number": [
|
| 811 |
+
{
|
| 812 |
+
"name": "count",
|
| 813 |
+
"value": 42
|
| 814 |
+
}
|
| 815 |
+
]
|
| 816 |
+
}
|
| 817 |
+
},
|
| 818 |
+
"name": "Set",
|
| 819 |
+
"type": "n8n-nodes-base.set",
|
| 820 |
+
"typeVersion": 1,
|
| 821 |
+
"position": [650, 300],
|
| 822 |
+
"id": "3"
|
| 823 |
+
}
|
| 824 |
+
```
|
| 825 |
+
""")
|
| 826 |
+
|
| 827 |
+
gr.Markdown("""
|
| 828 |
## Tips for Creating n8n-Compatible JSON
|
| 829 |
|
| 830 |
1. Ensure all JSON keys and values are properly quoted
|
|
|
|
| 837 |
""")
|
| 838 |
|
| 839 |
# Set up event handlers
|
| 840 |
+
# Modify to handle fallback mode
|
| 841 |
+
def handle_message(message, chat_history, is_fallback):
|
| 842 |
+
if is_fallback:
|
| 843 |
+
return simple_fallback_response(message, chat_history)
|
| 844 |
+
else:
|
| 845 |
+
return generate_response(message, chat_history)
|
| 846 |
+
|
| 847 |
send_btn.click(
|
| 848 |
+
handle_message,
|
| 849 |
+
inputs=[msg, chatbot, fallback_mode],
|
| 850 |
outputs=chatbot,
|
| 851 |
api_name="chat"
|
| 852 |
)
|
| 853 |
|
| 854 |
msg.submit(
|
| 855 |
+
handle_message,
|
| 856 |
+
inputs=[msg, chatbot, fallback_mode],
|
| 857 |
+
outputs=chatbot,
|
| 858 |
api_name=False
|
| 859 |
)
|
| 860 |
|
|
|
|
| 864 |
api_name="load_model"
|
| 865 |
)
|
| 866 |
|
| 867 |
+
use_fallback_btn.click(
|
| 868 |
+
toggle_fallback_mode,
|
| 869 |
+
inputs=[fallback_mode],
|
| 870 |
+
outputs=[fallback_mode, model_status],
|
| 871 |
+
api_name="fallback_mode"
|
| 872 |
+
)
|
| 873 |
+
|
| 874 |
update_prompt_btn.click(
|
| 875 |
update_system_prompt,
|
| 876 |
inputs=system_prompt_input,
|