File size: 4,817 Bytes
93d78da
 
 
 
 
13a423b
 
 
 
 
 
 
 
93d78da
 
 
844131c
93d78da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bfadd0
 
 
 
 
 
 
 
 
 
 
 
93d78da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
844131c
93d78da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
844131c
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
141
142
143
144
import os
import gradio as gr
from huggingface_hub import hf_hub_download
from llama_cpp import Llama

import spaces

# Dummy function to satisfy Hugging Face ZeroGPU startup check
@spaces.GPU
def dummy_gpu_fn():
    pass


# 1. Download the GGUF model file from Hugging Face Hub
# Adjust repo_id and filename if you named them differently when pushing to Hub
REPO_ID = "iamfebin/wish-lawyer-gguf"
FILENAME = "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf"

print(f"Downloading GGUF model '{FILENAME}' from repository '{REPO_ID}'...")
try:
    model_path = hf_hub_download(
        repo_id=REPO_ID,
        filename=FILENAME
    )
    print(f"Model downloaded successfully to: {model_path}")
except Exception as e:
    print(f"Error downloading model: {e}")
    print("If you pushed your model under a different filename or repository, please update REPO_ID and FILENAME in app.py.")
    model_path = None

# 2. Initialize the Llama model for CPU inference
llm = None
if model_path:
    print("Loading model into memory (using llama.cpp with 2 threads)...")
    try:
        llm = Llama(
            model_path=model_path,
            n_ctx=1024,      # Reduced from 2048 to lower memory footprint
            n_threads=2,     # Free Hugging Face Spaces provide 2 vCPUs
            use_mmap=False   # Read directly into RAM to prevent memory-mapped paging OOMs
        )
        print("Model loaded successfully!")
    except Exception as e:
        import traceback
        print("Failed to load model!")
        traceback.print_exc()

# 3. Prompt Template
wish_prompt_template = """### System:
You are an expert Wish Lawyer. Your job is to analyze dangerous human wishes, identify at least 3 hidden loopholes or catastrophic risks, and rewrite the wish into a single, legally ironclad sentence that protects the wisher completely.

### Context/Grantor:
{}

### Human Wish:
{}

### Risk Analysis (Internal Thought Process):
"""

def consult_wish_lawyer(wish, context):
    if not llm:
        return "Error: Model not loaded. Please check model download logs.", ""
        
    if not wish.strip():
        return "Please input a wish!", ""
        
    formatted_prompt = wish_prompt_template.format(context, wish)
    
    # Generate output using Llama.cpp CPU inference
    response = llm(
        formatted_prompt,
        max_tokens=512,
        temperature=0.5,
        top_p=0.9,
        stop=["### System:", "### Human Wish:", "### Context/Grantor:"]
    )
    
    generated_text = response["choices"][0]["text"].strip()
    
    # Split risk analysis and rewritten wish
    split_marker = "### Safer Rewritten Wish:"
    if split_marker not in generated_text:
        split_marker = "### Ironclad Rewritten Wish:"
        
    if split_marker in generated_text:
        parts = generated_text.split(split_marker)
        risk_analysis = parts[0].strip()
        rewritten_wish = parts[1].strip()
    else:
        risk_analysis = generated_text
        rewritten_wish = "No rewritten wish generated."
        
    return risk_analysis, rewritten_wish

# 4. Gradio UI Layout
with gr.Blocks() as demo:
    gr.Markdown(
        """
        # ⚖️ Wish Lawyer: Supernatural Legal Counsel
        Have you ever been worried about the literal interpretations of genies, crossroads devils, or trickster monkey paws?
        This is an instruction-tuned **Llama 3.1 8B** model trained to audit supernatural wishes for loopholes and redraft them into ironclad contracts.
        """
    )
    
    with gr.Row():
        with gr.Column():
            wish_input = gr.Textbox(
                label="Your Human Wish", 
                placeholder="e.g., I want to never feel tired.",
                lines=3
            )
            context_input = gr.Dropdown(
                label="Grantor / Context",
                choices=[
                    "A trickster monkey paw",
                    "An erratic genie",
                    "A deal with a crossroads devil",
                    "A suspicious corporate contract",
                    "Standard Wish Rules Apply"
                ],
                value="Standard Wish Rules Apply"
            )
            submit_btn = gr.Button("Consult the Wish Lawyer", variant="primary")
            
        with gr.Column():
            risk_output = gr.Textbox(
                label="Risk Analysis (Loopholes Identified)", 
                lines=6
            )
            wish_output = gr.Textbox(
                label="Safer Rewritten Wish (Ironclad)", 
                lines=4
            )
            
    submit_btn.click(
        fn=consult_wish_lawyer,
        inputs=[wish_input, context_input],
        outputs=[risk_output, wish_output]
    )

if __name__ == "__main__":
    demo.launch(theme=gr.themes.Soft(primary_hue="amber", secondary_hue="slate"))