1、pycharm的文件在哪?
在万WSL虚拟机中,去~就能找到文件
/mnt/f/26_01/python/test/py_code/
/mnt/本地目录
🚀 从零搭建本地AI对话系统:Ollama + DeepSeek-R1:7B + Streamlit
第一步:环境准备与Ollama部署
首先确保你的WSL Ubuntu环境就绪,然后安装核心工具Ollama。
-
安装Ollama
在WSL终端中执行以下命令一键安装:
curl -fsSL https://ollama.com/install.sh | sh安装完成后,验证是否成功:
ollama --version。 -
拉取DeepSeek-R1:7B模型
从Ollama的模型库中拉取模型:
ollama pull deepseek-r1:7b模型文件较大(约4.7GB),下载时间取决于你的网络速度。
-
启动Ollama服务
启动Ollama服务,它将提供本地API:
ollama serve此命令会启动服务并默认在
http://localhost:11434进行监听。请保持此终端窗口打开 ,或使用ollama serve &在后台运行。
第二步:创建Python虚拟环境
为避免包冲突,为项目创建一个独立的虚拟环境。
-
创建并激活虚拟环境:
python3 -m venv ai_chat_env source ai_chat_env/bin/activate -
安装必要的Python包:
pip install streamlit requests
第三步:开发Streamlit聊天应用
创建一个名为 app.py的Python文件,并写入以下代码。这段代码创建了Web界面并负责与Ollama API通信。
python
import streamlit as st
import requests
import json
import time
# 页面设置
st.set_page_config(
page_title="Ollama DeepSeek 对话",
page_icon="🤖",
layout="centered"
)
# 应用标题
st.title("🤖 Ollama + DeepSeek-R1:7B 对话")
st.markdown("---")
# 初始化会话状态
if 'messages' not in st.session_state:
st.session_state.messages = []
if 'conversation_history' not in st.session_state:
st.session_state.conversation_history = []
# 连接到 Ollama 的函数
def ask_ollama(user_message):
"""
发送请求到本地 Ollama 服务
"""
# Ollama API 地址(在 WSL 中运行)
url = "http://localhost:11434/api/chat"
# 构建消息历史
messages = []
# 添加系统提示
messages.append({
"role": "system",
"content": "你是一个有帮助的AI助手,使用中文回答。"
})
# 添加历史对话(最近3轮)
for msg in st.session_state.messages[-6:]:
messages.append(msg)
# 添加当前用户消息
messages.append({"role": "user", "content": user_message})
# 请求数据
payload = {
"model": "deepseek-r1:7b",
"messages": messages,
"stream": False,
"options": {
"temperature": 0.7,
"num_predict": 256
}
}
try:
# 发送请求
response = requests.post(
url,
json=payload,
timeout=60
)
if response.status_code == 200:
result = response.json()
return result['message']['content']
else:
return f"❌ 请求失败 (状态码: {response.status_code})"
except requests.exceptions.ConnectionError:
return "⚠️ 无法连接到 Ollama 服务!\n\n请确保:\n1. 在 WSL 终端运行 `ollama serve`\n2. 模型已下载:`ollama pull deepseek-r1:7b`"
except Exception as e:
return f"❌ 发生错误: {str(e)}"
# 侧边栏 - 设置和信息
with st.sidebar:
st.header("⚙️ 设置")
# 清除对话按钮
if st.button("🗑️ 清除对话历史", use_container_width=True):
st.session_state.messages = []
st.session_state.conversation_history = []
st.rerun()
st.divider()
st.header("📊 状态信息")
# 显示当前模型
st.info(f"**模型:** deepseek-r1:7b")
st.info(f"**对话轮次:** {len(st.session_state.messages) // 2}")
st.divider()
# 快速测试连接
if st.button("🔗 测试连接", use_container_width=True):
with st.spinner("测试连接中..."):
test_result = ask_ollama("你好,请回复'连接成功'。")
st.success(f"测试结果: {test_result[:50]}...")
# 显示对话历史
st.subheader("💭 对话历史")
# 如果还没有对话,显示提示
if not st.session_state.messages:
st.info("👆 在下方输入框中输入消息开始对话")
else:
# 显示所有消息
for i, message in enumerate(st.session_state.messages):
if i % 2 == 0: # 用户消息
with st.chat_message("user"):
st.markdown(f"**你:** {message['content']}")
else: # AI消息
with st.chat_message("assistant"):
st.markdown(f"**AI:** {message['content']}")
# 输入区域
st.divider()
st.subheader("📝 输入你的消息")
# 创建输入表单
with st.form(key="chat_form", clear_on_submit=True):
user_input = st.text_area(
"输入消息:",
height=100,
placeholder="输入你想问的问题...",
key="user_input_area"
)
col1, col2 = st.columns([1, 1])
with col1:
submit_button = st.form_submit_button(
"🚀 发送",
use_container_width=True,
type="primary"
)
with col2:
example_button = st.form_submit_button(
"💡 示例问题",
use_container_width=True
)
# 处理示例按钮
if example_button:
example_questions = [
"你好,请介绍一下你自己",
"什么是人工智能?",
"写一首关于秋天的诗",
"解释一下机器学习的基本概念",
"如何学习编程?"
]
import random
user_input = random.choice(example_questions)
st.session_state.user_input_area = user_input
st.rerun()
# 处理发送按钮
if submit_button and user_input.strip():
# 添加用户消息到历史
st.session_state.messages.append({
"role": "user",
"content": user_input
})
# 显示用户消息
with st.chat_message("user"):
st.markdown(f"**你:** {user_input}")
# 获取AI响应
with st.spinner("🤖 DeepSeek 正在思考..."):
ai_response = ask_ollama(user_input)
# 添加AI响应到历史
st.session_state.messages.append({
"role": "assistant",
"content": ai_response
})
# 显示AI响应
with st.chat_message("assistant"):
st.markdown(f"**AI:** {ai_response}")
# 滚动到最新消息
st.rerun()
# 页脚信息
st.markdown("---")
st.caption("""
💡 **使用说明:**
1. 确保在 WSL 终端中运行 `ollama serve` 启动服务
2. 确保已下载模型: `ollama pull deepseek-r1:7b`
3. 输入问题后点击"发送"按钮
4. 使用侧边栏的"清除对话历史"按钮开始新的对话
""")
# 添加简单的 CSS 样式
st.markdown("""
<style>
.stTextArea textarea {
font-size: 16px;
}
.stButton button {
font-weight: bold;
}
.stChatMessage {
padding: 10px;
border-radius: 10px;
margin: 10px 0;
}
div[data-testid="stChatMessage"] {
border-left: 4px solid #4CAF50;
padding-left: 10px;
}
div[data-testid="stChatMessage"]:nth-child(even) {
border-left: 4px solid #2196F3;
}
</style>
""", unsafe_allow_html=True)
第四步:运行应用
在WSL终端中,确保位于 app.py所在目录,并且虚拟环境已激活,然后运行:
streamlit run app.py
命令执行后,Streamlit通常会自动在你的默认浏览器中打开应用 (地址通常是 http://localhost:8501)。如果未自动打开,你可以手动在浏览器中输入这个地址。
第五步:开始对话与故障排查
现在应该能看到一个简洁的聊天界面。
-
开始对话:在底部输入框输入问题,比如"介绍一下你自己",然后按回车或点击发送。
-
故障排查:
-
如果连接失败 :首先检查运行
ollama serve的终端是否正常,没有报错信息。 -
验证Ollama API :可以新开一个终端,用命令
curl http://localhost:11434/api/tags测试,如果返回包含模型名称的JSON信息,说明API服务正常。 -
端口冲突:如果8501端口被占用,Streamlit会提示并使用新端口(如8502),按提示访问即可。
-
💡 核心要点与进阶技巧
| 环节 | 关键点/技巧 | 说明 |
|---|---|---|
| Ollama服务 | 保持运行 | 运行Streamlit应用时,ollama serve必须始终在后台运行。 |
| 对话体验 | 上下文记忆 | 代码通过 st.session_state.messages自动维护对话历史,实现连续对话。 |
| 性能优化 | 硬件资源 | 如果拥有NVIDIA显卡并配置了CUDA,Ollama会自动利用GPU加速推理。 |
| 功能扩展 | 模型切换 | 可在侧边栏添加下拉框,集成 ollama list获取的模型列表,让用户自由切换不同模型。 |
| 部署分享 | 网络访问 | 除了本地访问,你还可以通过 http://<你的WSL IP>:8501在同局域网下的其他设备(如手机、平板)上访问此应用。 |
