Mohansai2004 commited on
Commit
9b556bc
·
1 Parent(s): 0222994

feat: switch to deepseek model for token-free operation

Browse files
Files changed (3) hide show
  1. README.md +14 -23
  2. app.py +77 -310
  3. requirements.txt +2 -23
README.md CHANGED
@@ -1,36 +1,27 @@
1
  ---
2
- title: DeepSeek Code Assistant
3
- emoji: 🚀
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: streamlit
7
  sdk_version: 1.41.1
8
  app_file: app.py
9
  pinned: false
10
- short_description: Advanced Code Generation with Enhanced UI
11
  ---
12
 
13
- # DeepSeek Code Assistant Pro
14
 
15
- A powerful code generation tool with enhanced UI features:
16
- - Modern, responsive interface
17
- - Advanced code customization
18
- - Multiple template options
19
- - Syntax highlighting
20
- - One-click code copying
21
- - Code downloading
22
 
23
  ## Features
24
- - Interactive code generation
25
- - Real-time preview
26
- - Multiple programming languages
27
- - Custom templates
28
- - Error handling options
29
- - Automatic commenting
30
- - Test generation
31
 
32
- ## Pro Tips
33
- - Use detailed descriptions
34
- - Specify requirements clearly
35
- - Select appropriate templates
36
- - Enable useful options
 
1
  ---
2
+ title: AI Chat Assistant
3
+ emoji: 💭
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: streamlit
7
  sdk_version: 1.41.1
8
  app_file: app.py
9
  pinned: false
10
+ short_description: ChatGPT-like interface using Ollama
11
  ---
12
 
13
+ # AI Chat Assistant
14
 
15
+ Simple and efficient chat interface powered by Ollama DeepSeek model.
 
 
 
 
 
 
16
 
17
  ## Features
18
+ - Clean chat interface
19
+ - Message history
20
+ - Streaming responses
21
+ - Context awareness
22
+ - Local inference
 
 
23
 
24
+ ## Usage
25
+ - Type your message and press Enter
26
+ - Clear chat history using sidebar button
27
+ - Maintains conversation context
 
app.py CHANGED
@@ -1,354 +1,121 @@
1
  import streamlit as st
2
- # Set page config must be the first Streamlit command
3
- st.set_page_config(
4
- page_title="DeepSeek Coding Assistant",
5
- page_icon="🚀",
6
- layout="wide",
7
- initial_sidebar_state="expanded"
8
- )
9
-
10
- from transformers import AutoTokenizer, AutoModelForCausalLM
11
  import torch
12
- import gc
13
- from PIL import Image
14
- import io
15
  import logging
16
- import sys
17
-
18
- # Set up logging
19
- logging.basicConfig(level=logging.DEBUG)
20
- logger = logging.getLogger(__name__)
21
 
22
- # Debug container after page config
23
- debug_container = st.empty()
 
24
 
25
- def debug_info(msg):
26
- logger.debug(msg)
27
- if st.session_state.get('show_debug', False):
28
- debug_container.info(msg)
29
-
30
- # Add custom CSS
31
  st.markdown("""
32
  <style>
33
- .main {
34
- padding: 2rem;
35
- }
36
- .stButton button {
37
- width: 100%;
38
- border-radius: 5px;
39
- height: 3em;
40
- background-color: #4CAF50;
41
- color: white;
42
- }
43
- .stTextInput > div > div > input {
44
- border-radius: 5px;
45
- }
46
- .stSelectbox > div > div > select {
47
- border-radius: 5px;
48
- }
49
- .output-container {
50
- background-color: #f0f2f6;
51
- padding: 20px;
52
- border-radius: 10px;
53
- margin: 10px 0;
54
- }
55
- .success-message {
56
- color: #4CAF50;
57
- font-weight: bold;
58
- }
59
- .error-message {
60
- color: #ff4444;
61
- font-weight: bold;
62
- }
63
  </style>
64
  """, unsafe_allow_html=True)
65
 
66
- # Add debug toggle to sidebar
67
- def create_sidebar():
68
- with st.sidebar:
69
- st.image("https://raw.githubusercontent.com/streamlit/streamlit/develop/examples/streamlit_app_example.png",
70
- width=100)
71
- st.title("🛠️ Settings")
72
-
73
- # Add debug toggle
74
- st.session_state.show_debug = st.checkbox("Show Debug Info", value=False)
75
-
76
- task = st.selectbox(
77
- "Select Task",
78
- ["💻 Code Generation", "🖼️ Image Analysis", "📚 Concept Explanation"]
79
- )
80
-
81
- st.markdown("---")
82
-
83
- if st.button("♻️ Clear Cache", use_container_width=True):
84
- st.cache_resource.clear()
85
- st.success("Cache cleared successfully!")
86
-
87
- st.markdown("""
88
- ### 🌟 Pro Tips
89
- - Use detailed descriptions
90
- - Specify edge cases
91
- - Include example inputs/outputs
92
- """)
93
-
94
- return task.split()[1] # Return without emoji
95
-
96
  @st.cache_resource
97
  def load_model():
 
 
98
  try:
99
- debug_info("Loading model...")
100
- model_id = "deepseek-ai/deepseek-coder-1.3b-base"
101
-
102
- debug_info(f"Initializing tokenizer from {model_id}")
103
  tokenizer = AutoTokenizer.from_pretrained(
104
- model_id,
105
- trust_remote_code=True,
106
- padding_side='left',
107
- truncation_side='left'
108
  )
 
109
 
110
- # Validate tokenizer configuration
111
- debug_info(f"Tokenizer pad_token: {tokenizer.pad_token}")
112
- debug_info(f"Tokenizer vocab size: {len(tokenizer)}")
113
-
114
- if not hasattr(tokenizer, 'pad_token') or tokenizer.pad_token is None:
115
- debug_info("Setting default pad token")
116
- tokenizer.pad_token = '[PAD]'
117
-
118
- debug_info("Loading model weights...")
119
  model = AutoModelForCausalLM.from_pretrained(
120
- model_id,
121
  torch_dtype=torch.float32,
122
  low_cpu_mem_usage=True,
123
- device_map="cpu",
124
- max_memory={'cpu': '16GB'}
125
- )
126
 
127
- # Validate model configuration
128
- debug_info(f"Model device: {next(model.parameters()).device}")
129
- debug_info(f"Model memory: {torch.cuda.max_memory_allocated() if torch.cuda.is_available() else 'CPU only'}")
130
-
131
- # Ensure model knows about pad token
132
- model.config.pad_token_id = tokenizer.pad_token_id
133
- model.config.eos_token_id = tokenizer.eos_token_id
134
- model.eval()
135
- torch.set_num_threads(8)
136
- gc.collect()
137
  return model, tokenizer
138
 
139
  except Exception as e:
140
- logger.error(f"Model loading error: {str(e)}")
141
  st.error(f"Error loading model: {str(e)}")
142
  st.stop()
143
 
144
- def generate_response_streaming(prompt, model, tokenizer, placeholder):
145
  try:
146
- debug_info("Starting text generation...")
147
- debug_info(f"Input prompt length: {len(prompt)}")
148
-
149
- # Validate inputs
150
- if not all([model, tokenizer, placeholder]):
151
- raise ValueError("Missing required components")
152
-
153
- code_prompt = f"""Write professional code based on the given requirements.
154
- Language: {prompt.split('code for:')[0] if 'code for:' in prompt else 'any'}
155
- Requirements: {prompt}
156
 
157
- Here's the implementation:"""
 
 
158
 
159
- # Create input tensors with proper attention masks
160
- inputs = tokenizer(
161
- code_prompt,
162
- return_tensors="pt",
163
- padding=True,
164
- truncation=True,
165
- max_length=1024,
166
- add_special_tokens=True,
167
- return_attention_mask=True
168
- )
169
-
170
- # Ensure input tensors are properly shaped
171
- attention_mask = inputs['attention_mask']
172
- input_ids = inputs['input_ids']
173
-
174
- generated_text = ""
175
  with torch.inference_mode():
176
- while input_ids.shape[1] < 2048:
177
- outputs = model.generate(
178
- input_ids=input_ids,
179
- attention_mask=attention_mask,
180
- max_new_tokens=1, # Generate one token at a time
181
- pad_token_id=tokenizer.pad_token_id,
182
- eos_token_id=tokenizer.eos_token_id,
183
- do_sample=True,
184
- temperature=0.5,
185
- top_p=0.95,
186
- repetition_penalty=1.1,
187
- )
188
-
189
- # Get next token and update tensors
190
- next_token = outputs[:, -1:]
191
- input_ids = torch.cat([input_ids, next_token], dim=1)
192
- attention_mask = torch.ones_like(input_ids)
193
-
194
- # Update display
195
- current_text = tokenizer.decode(input_ids[0], skip_special_tokens=True)
196
- generated_text = current_text.replace(code_prompt, "").strip()
197
- placeholder.code(generated_text)
198
-
199
- # Check for completion
200
- if next_token[0, 0].item() == tokenizer.eos_token_id:
201
- break
202
-
203
- # Add validation checks during generation
204
- if attention_mask.shape != input_ids.shape:
205
- debug_info(f"Shape mismatch - attention: {attention_mask.shape}, ids: {input_ids.shape}")
206
 
207
- debug_info(f"Generation complete. Output length: {len(generated_text)}")
208
- return generated_text
 
 
209
 
210
  except Exception as e:
211
- logger.error(f"Generation error: {str(e)}")
212
- return f"Error: {str(e)}"
213
 
214
- def code_generation_ui():
215
- debug_info("Initializing UI components")
216
-
217
- # Validate PROGRAMMING_LANGUAGES is defined
218
- if 'PROGRAMMING_LANGUAGES' not in globals():
219
- st.error("Programming languages configuration not found")
220
- return
221
-
222
- col1, col2 = st.columns([2, 1])
223
-
224
- with col1:
225
- st.markdown("### 📝 Code Requirements")
226
- category = st.selectbox(
227
- "Domain",
228
- list(PROGRAMMING_LANGUAGES.keys()),
229
- help="Select the type of application"
230
- )
231
-
232
- language = st.selectbox(
233
- "Language",
234
- PROGRAMMING_LANGUAGES[category],
235
- help="Choose programming language"
236
- )
237
-
238
- template = st.selectbox(
239
- "Template",
240
- ["Basic Script", "Function", "Class", "Full Program", "API", "Database"],
241
- help="Select code structure"
242
- )
243
-
244
- with col2:
245
- st.markdown("### ⚙️ Options")
246
- add_comments = st.checkbox("Add Comments", value=True)
247
- include_tests = st.checkbox("Include Tests")
248
- error_handling = st.checkbox("Error Handling")
249
-
250
- prompt = st.text_area(
251
- "Describe Your Code Requirements",
252
- placeholder="Example: Create a function that takes a list of numbers and returns the sum of even numbers...",
253
- height=150
254
- )
255
-
256
- col1, col2, col3 = st.columns([1, 1, 1])
257
- with col2:
258
- generate = st.button("🚀 Generate Code", use_container_width=True)
259
-
260
- if generate and prompt:
261
- debug_info(f"Generating code for language: {language}")
262
- debug_info(f"Template: {template}")
263
- debug_info(f"Options: comments={add_comments}, tests={include_tests}")
264
-
265
- st.markdown("### 📋 Generated Code")
266
-
267
- # Create a placeholder for streaming output
268
- code_placeholder = st.empty()
269
-
270
- with st.spinner("🔮 Generating..."):
271
- model, tokenizer = load_model()
272
- code = generate_response_streaming(prompt, model, tokenizer, code_placeholder)
273
-
274
- # After generation complete, show final version with copy/download buttons
275
- with st.expander("Final Code", expanded=True):
276
- st.code(code, language=language.lower())
277
-
278
- col1, col2 = st.columns([1, 1])
279
- with col1:
280
- st.download_button(
281
- "💾 Download Code",
282
- code,
283
- file_name=f"generated_code.{language.lower()}",
284
- mime="text/plain"
285
- )
286
- with col2:
287
- st.button("📋 Copy to Clipboard")
288
-
289
- # Add global variables check
290
- if 'PROGRAMMING_LANGUAGES' not in globals():
291
- PROGRAMMING_LANGUAGES = {
292
- "Web Development": ["HTML", "CSS", "JavaScript", "TypeScript", "PHP"],
293
- "Backend": ["Python", "Java", "C#", "Ruby", "Go", "Node.js"],
294
- "Data & ML": ["Python", "R", "SQL", "Julia"],
295
- "Mobile": ["Swift", "Kotlin", "Java", "React Native"],
296
- "System": ["C", "C++", "Rust", "Shell"]
297
- }
298
- debug_info("Initialized PROGRAMMING_LANGUAGES")
299
-
300
- def handle_text_generation(prompt, task_type="code"):
301
- try:
302
- model, tokenizer = load_model()
303
- placeholder = st.empty()
304
-
305
- if task_type == "code":
306
- prompt = f"""Write professional code based on the given requirements.
307
- Requirements: {prompt}"""
308
- else:
309
- prompt = f"Explain this concept: {prompt}"
310
-
311
- return generate_response_streaming(prompt, model, tokenizer, placeholder)
312
- except Exception as e:
313
- debug_info(f"Error in text generation: {str(e)}")
314
- return f"Error: {str(e)}"
315
 
316
  def main():
317
- task = create_sidebar()
 
318
 
319
- st.markdown("# 🚀 DeepSeek Coding Assistant")
320
- st.markdown("---")
 
 
 
 
 
 
 
 
 
321
 
322
- if task == "Code Generation":
323
- code_generation_ui()
324
- elif task == "Image Analysis":
325
- uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
326
- if uploaded_file:
327
- image = Image.open(uploaded_file)
328
- st.image(image, caption="Uploaded Image")
 
 
 
 
 
 
329
 
330
- analysis_type = st.selectbox(
331
- "What would you like to know?",
332
- ["Describe Image", "Technical Analysis", "Extract Text"]
 
333
  )
334
 
335
- if st.button("Analyze"):
336
- with st.spinner("Analyzing image..."):
337
- response = handle_text_generation(
338
- f"Analyze this image for {analysis_type}:",
339
- task_type="analysis"
340
- )
341
- st.write(response)
342
- else: # Concept Explanation
343
- concept = st.text_input("Enter the concept you want to understand:")
344
- if st.button("Explain"):
345
- if concept:
346
- with st.spinner("Generating explanation..."):
347
- response = handle_text_generation(
348
- concept,
349
- task_type="explain"
350
- )
351
- st.markdown(response)
352
 
353
  if __name__ == "__main__":
354
  main()
 
1
  import streamlit as st
2
+ from transformers import AutoModelForCausalLM, AutoTokenizer
 
 
 
 
 
 
 
 
3
  import torch
 
 
 
4
  import logging
 
 
 
 
 
5
 
6
+ # Configure page and logging
7
+ st.set_page_config(page_title="AI Chat Assistant", page_icon="💭", layout="wide")
8
+ logging.basicConfig(level=logging.INFO)
9
 
10
+ # Custom CSS for chat interface
 
 
 
 
 
11
  st.markdown("""
12
  <style>
13
+ .stChat { padding: 20px; border-radius: 10px; }
14
+ .user-message { background-color: #e6f3ff; }
15
+ .assistant-message { background-color: #f0f2f6; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  </style>
17
  """, unsafe_allow_html=True)
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  @st.cache_resource
20
  def load_model():
21
+ model_name = "deepseek-ai/deepseek-chat-1.3b-base" # Smaller DeepSeek model
22
+
23
  try:
 
 
 
 
24
  tokenizer = AutoTokenizer.from_pretrained(
25
+ model_name,
26
+ trust_remote_code=True
 
 
27
  )
28
+ tokenizer.pad_token = tokenizer.eos_token
29
 
 
 
 
 
 
 
 
 
 
30
  model = AutoModelForCausalLM.from_pretrained(
31
+ model_name,
32
  torch_dtype=torch.float32,
33
  low_cpu_mem_usage=True,
34
+ trust_remote_code=True
35
+ ).to("cpu")
 
36
 
 
 
 
 
 
 
 
 
 
 
37
  return model, tokenizer
38
 
39
  except Exception as e:
 
40
  st.error(f"Error loading model: {str(e)}")
41
  st.stop()
42
 
43
+ def generate_response(prompt, model, tokenizer):
44
  try:
45
+ # Format prompt for DeepSeek chat
46
+ chat_prompt = f"Human: {prompt}\n\nAssistant: Let me help you with that."
 
 
 
 
 
 
 
 
47
 
48
+ inputs = tokenizer(chat_prompt, return_tensors="pt", padding=True)
49
+ message_placeholder = st.empty()
50
+ response_text = ""
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  with torch.inference_mode():
53
+ outputs = model.generate(
54
+ inputs["input_ids"],
55
+ max_length=512,
56
+ temperature=0.7,
57
+ top_p=0.95,
58
+ do_sample=True,
59
+ pad_token_id=tokenizer.eos_token_id,
60
+ attention_mask=inputs["attention_mask"],
61
+ num_return_sequences=1,
62
+ repetition_penalty=1.2
63
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
66
+ # Extract assistant's response
67
+ response = response.split("Assistant:")[-1].strip()
68
+ return response
69
 
70
  except Exception as e:
71
+ st.error(f"Error: {str(e)}")
72
+ return None
73
 
74
+ def init_chat():
75
+ if "messages" not in st.session_state:
76
+ st.session_state.messages = []
77
+ st.session_state.model, st.session_state.tokenizer = load_model()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  def main():
80
+ st.title("💭 AI Chat Assistant")
81
+ init_chat()
82
 
83
+ # Sidebar with controls
84
+ with st.sidebar:
85
+ st.markdown("### Chat Controls")
86
+ if st.button("🗑️ Clear Chat", use_container_width=True):
87
+ st.session_state.messages = []
88
+ st.rerun()
89
+
90
+ # Display chat messages
91
+ for message in st.session_state.messages:
92
+ with st.chat_message(message["role"]):
93
+ st.markdown(message["content"])
94
 
95
+ # Chat input
96
+ if prompt := st.chat_input("Send a message..."):
97
+ # Add user message
98
+ st.session_state.messages.append({"role": "user", "content": prompt})
99
+ with st.chat_message("user"):
100
+ st.markdown(prompt)
101
+
102
+ # Generate and display assistant response
103
+ with st.chat_message("assistant"):
104
+ context = "\n".join([
105
+ f"{m['role']}: {m['content']}"
106
+ for m in st.session_state.messages[-3:]
107
+ ])
108
 
109
+ response = generate_response(
110
+ context,
111
+ st.session_state.model,
112
+ st.session_state.tokenizer
113
  )
114
 
115
+ if response:
116
+ st.session_state.messages.append(
117
+ {"role": "assistant", "content": response}
118
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  if __name__ == "__main__":
121
  main()
requirements.txt CHANGED
@@ -1,28 +1,7 @@
1
  # Core dependencies
2
  streamlit>=1.41.1
3
- watchdog>=3.0.0
4
-
5
- # Model and ML
6
  torch>=2.0.0
7
- transformers>=4.33.0
8
  accelerate>=0.21.0
9
  sentencepiece>=0.1.99
10
- einops>=0.6.1
11
- scikit-learn>=1.3.0
12
-
13
- # UI enhancements
14
- streamlit-option-menu>=0.3.2
15
- streamlit-ace>=0.1.1
16
- streamlit-extras>=0.3.0
17
- streamlit-code-editor>=0.1.6
18
-
19
- # Image processing
20
- Pillow>=9.0.0
21
-
22
- # Performance optimizations
23
- rich>=13.5.2
24
- tqdm>=4.65.0
25
- numpy>=1.24.0
26
-
27
- # Memory management
28
- psutil>=5.9.0
 
1
  # Core dependencies
2
  streamlit>=1.41.1
 
 
 
3
  torch>=2.0.0
4
+ transformers>=4.31.0
5
  accelerate>=0.21.0
6
  sentencepiece>=0.1.99
7
+ einops>=0.6.1