Invescoz commited on
Commit
2795928
·
verified ·
1 Parent(s): 564e391

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -159
app.py CHANGED
@@ -1,163 +1,42 @@
1
- import gradio as gr
2
- import subprocess
3
- import sys
4
  import torch
5
- import requests
6
- from bs4 import BeautifulSoup
7
- from sentence_transformers import SentenceTransformer, util
8
- from duckduckgo_search import DDGS
9
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
10
- from typing import Generator
11
 
12
- # Install dependencies at runtime if not found
13
- try:
14
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
15
- except ImportError:
16
- print("Installing transformers...")
17
- subprocess.check_call([sys.executable, "-m", "pip", "install", "transformers==4.44.2"])
18
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
19
-
20
- # Initialize model and tokenizer
21
- model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
22
- try:
23
- tokenizer = AutoTokenizer.from_pretrained(model_name)
24
- model = AutoModelForCausalLM.from_pretrained(
25
- model_name,
26
- device_map="auto", # Offload to CPU
27
- torch_dtype=torch.float16, # Optimize memory
28
- trust_remote_code=True,
29
- low_cpu_mem_usage=True # Reduce memory overhead
30
- )
31
- except Exception as e:
32
- print(f"Error loading model: {e}")
33
- raise
34
-
35
- # Initialize sentence-transformers for indexing
36
- embedder = SentenceTransformer('all-MiniLM-L6-v2')
37
-
38
- # In-memory index (list of documents and embeddings)
39
- document_index = []
40
- embeddings = []
41
-
42
- def crawl_website(url: str) -> str:
43
- """Crawl a website and return text content."""
44
- try:
45
- response = requests.get(url, timeout=10)
46
- response.raise_for_status()
47
- soup = BeautifulSoup(response.text, 'html.parser')
48
- text = soup.get_text(separator=' ', strip=True)
49
- return text[:2000] # Limit to 2000 chars for performance
50
- except Exception as e:
51
- return f"Error crawling {url}: {str(e)}"
52
-
53
- def index_data(text: str):
54
- """Index crawled data for similarity search."""
55
- document_index.append(text)
56
- embeddings.append(embedder.encode(text))
57
- return "Data indexed successfully."
58
-
59
- def search_index(query: str) -> str:
60
- """Search indexed data using similarity."""
61
- if not embeddings:
62
- return "No data indexed yet."
63
- query_emb = embedder.encode(query)
64
- hits = util.semantic_search(query_emb, embeddings, top_k=1)[0]
65
- if hits:
66
- return document_index[hits[0]['corpus_id']][:500] # Limit to 500 chars
67
- return "No relevant data found."
68
-
69
- def web_search(query: str) -> str:
70
- """Perform web search using DuckDuckGo."""
71
- try:
72
- with DDGS() as ddgs:
73
- results = list(ddgs.text(query, max_results=3))
74
- return "\n".join([f"{r['title']}: {r['body']}" for r in results])
75
- except Exception as e:
76
- return f"Error performing web search: {str(e)}"
77
-
78
- def extract_image_links(url: str) -> str:
79
- """Extract image links from a webpage."""
80
- try:
81
- response = requests.get(url, timeout=10)
82
- response.raise_for_status()
83
- soup = BeautifulSoup(response.text, 'html.parser')
84
- images = soup.find_all('img')
85
- links = [img['src'] for img in images if 'src' in img.attrs]
86
- return "\n".join(links[:5]) or "No images found."
87
- except Exception as e:
88
- return f"Error extracting images from {url}: {str(e)}"
89
-
90
- def generate_ai_reasoning(prompt: str) -> Generator[str, None, None]:
91
- """
92
- Uses TinyLlama for AI reasoning, integrating web crawling, indexing, search, and image links.
93
- """
94
- system_prompt = (
95
- "You are an AI reasoning assistant like Grok, capable of logical analysis and web operations. "
96
- "Given a user prompt, provide a reasoned response. You can crawl websites, index data, perform web searches, "
97
- "and extract image links if requested. Stream the output line by line. Use bullet points for key insights. "
98
- "If the prompt is vague (e.g., 'Hi'), request more details and provide a general response. "
99
- "For astrology queries, offer vivid, optimistic predictions based on user-provided zodiac or birth date."
100
- )
101
-
102
- # Handle specific commands
103
- response_prefix = ""
104
- if "crawl" in prompt.lower():
105
- url = prompt.split("crawl")[-1].strip().split()[0]
106
- crawled_text = crawl_website(url)
107
- index_data(crawled_text)
108
- response_prefix = f"Crawled {url}:\n{crawled_text[:500]}\n\nIndexed data.\n\n"
109
- elif "search index" in prompt.lower():
110
- query = prompt.split("search index")[-1].strip()
111
- response_prefix = f"Indexed search result:\n{search_index(query)}\n\n"
112
- elif "search web" in prompt.lower():
113
- query = prompt.split("search web")[-1].strip()
114
- response_prefix = f"Web search results:\n{web_search(query)}\n\n"
115
- elif "image links" in prompt.lower():
116
- url = prompt.split("image links")[-1].strip().split()[0]
117
- response_prefix = f"Image links from {url}:\n{extract_image_links(url)}\n\n"
118
-
119
- full_prompt = f"<|SYSTEM|> {system_prompt}\n<|USER|> {prompt}\n<|ASSISTANT|> {response_prefix}"
120
-
121
- # Tokenize input
122
- inputs = tokenizer(full_prompt, return_tensors="pt").to("cpu")
123
-
124
- # Stream output
125
- streamer = TextStreamer(tokenizer, skip_prompt=True)
126
- for token in model.generate(
127
- **inputs,
128
- max_length=1000,
129
- temperature=0.7,
130
- top_p=0.9,
131
- do_sample=True,
132
- streamer=streamer
133
- ):
134
- content = tokenizer.decode(token, skip_special_tokens=True)
135
- if content:
136
- yield content
137
-
138
- # Gradio interface with streaming
139
- def live_ai_reasoner(prompt: str):
140
- """Handles streaming AI reasoning."""
141
- output = ""
142
- for chunk in generate_ai_reasoning(prompt):
143
- output += chunk
144
- yield output
145
-
146
- # Gradio app
147
- with gr.Blocks() as demo:
148
- gr.Markdown("# Invescoz AI Studio: AI Reasoning with Web Tools")
149
- prompt_input = gr.Textbox(
150
- label="Enter your query",
151
- placeholder="e.g., Crawl https://example.com for Scorpio predictions, Search web for AI trends, or Image links from https://example.com"
152
- )
153
- output_display = gr.Textbox(label="AI Response", interactive=False, lines=10)
154
- submit_button = gr.Button("Reason")
155
 
156
- submit_button.click(
157
- fn=live_ai_reasoner,
158
- inputs=prompt_input,
159
- outputs=output_display
160
- )
161
 
162
- # Launch the app (handled by Hugging Face Spaces)
163
- demo.launch()
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM
4
  import torch
 
 
 
 
 
 
5
 
6
+ app = FastAPI()
7
+
8
+ # Load Qwen2-1.5B-Instruct model and tokenizer
9
+ model_name = "Qwen/Qwen2-1.5B-Instruct"
10
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
11
+ model = AutoModelForCausalLM.from_pretrained(
12
+ model_name,
13
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
14
+ device_map="auto"
15
+ )
16
+
17
+ class ChatRequest(BaseModel):
18
+ message: str
19
+
20
+ @app.post("/chat")
21
+ async def chat(request: ChatRequest):
22
+ # Prepare input for Qwen model
23
+ messages = [{"role": "user", "content": request.message}]
24
+ text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
25
+ inputs = tokenizer([text], return_tensors="pt").to(model.device)
26
+
27
+ # Generate response
28
+ with torch.no_grad():
29
+ outputs = model.generate(
30
+ **inputs,
31
+ max_new_tokens=200,
32
+ temperature=0.7,
33
+ do_sample=True,
34
+ top_p=0.8
35
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
38
+ return {"response": response.strip()}
 
 
 
39
 
40
+ if __name__ == "__main__":
41
+ import uvicorn
42
+ uvicorn.run(app, host="0.0.0.0", port=8000)