本地搭建deepseek-r1

一、下载ollama(官网下载比较慢,可以找个网盘资源下)

二、安装ollama

三、打开cmd,拉取模型deepseek-r1:14b(根据显存大小选择模型大小)

ollama pull deepseek-r1:14b

四、运行模型

ollama run deepseek-r1:14b

五、使用网页api访问,可以使用openweb-ui,也可以自己实现页面,下面是使用vue实现的页面

复制代码
const ChildOllama = {
    data() {
        return {
            userInput: '',
            chatHistory: [],
            // 请根据实际情况修改 Ollama API 的 URL
            ollamaApiUrl: 'http://localhost:11434/v1/chat',
            currentResponse: ''
        }
    },
    watch: {
        // 监听 messages 数组的变化
        chatHistory: {
            handler() {
                // 数据变化时将滚动条移动到最下方
                this.scrollToBottom();
            },
            deep: true
        }
    }
    ,
    methods: {
        // 将滚动条移动到最下方的方法
        scrollToBottom() {
            // 获取滚动 div 的引用
            const scrollDiv = this.$refs.scrollDiv;
            // 设置滚动条位置到最下方
            scrollDiv.scrollTop = scrollDiv.scrollHeight;
        }
        ,
        async sendMessage() {
            if (this.userInput.trim() === '') return;

            // 添加用户消息到历史记录
            const userMessage = { role: 'user', content: this.userInput };
            this.chatHistory.push(userMessage);

            try {
                // 构造请求数据
                const response = await fetch('http://localhost:11434/api/chat', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        model: 'deepseek-r1:14b', // 使用的模型
                        messages: this.chatHistory,
                        stream: true, // 启用流式传输
                    }),
                });
                if (!response.ok) {
                    throw new Error(`请求失败,状态码: ${response.status}`);
                }
                this.currentResponse = '';

                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let done = false;
                while (!done) {
                    const { value, done: readerDone } = await reader.read();
                    done = readerDone;
                    if (value) {
                        const chunk = decoder.decode(value, { stream: true });
                        const lines = chunk.split('\n').filter(line => line.trim() !== '');
                        for (const line of lines) {
                            if (line) {
                                try {
                                    const data = JSON.parse(line.replace(/^data: /, ''));
                                    if (data.done) {
                                        // 流式响应结束,添加完整回复到历史记录
                                        const ollamaMessage = { role: 'assistant', content: this.currentResponse };
                                        this.chatHistory.push(ollamaMessage);
                                    } else {
                                        this.currentResponse += data.message.content || '';
                                    }
                                } catch (error) {
                                    console.error('Error parsing JSON:', error);
                                }
                            }
                        }
                    }
                }
            } catch (error) {
                console.error('Error sending message:', error);
            }

            // 清空输入框
            this.userInput = '';
            // try {
            //     // 将当前输入添加到对话历史中
            //     this.conversationHistory.push({ role: 'user', content: this.inputText });
            //
            //     // 构造完整的提示信息,包含对话历史
            //     let fullPrompt = '';
            //     this.conversationHistory.forEach((item) => {
            //         fullPrompt += `${item.role === 'user' ? '用户: ' : '助手: '}${item.content}\n`;
            //     });
            //
            //     // 清空之前的响应文本
            //     this.responseText = '';
            //     // 发起流式请求
            //     const response = await fetch('http://localhost:11434/api/generate', {
            //         method: 'POST',
            //         headers: {
            //             'Content-Type': 'application/json'
            //         },
            //         body: JSON.stringify({
            //             model: 'deepseek-r1:14b',
            //             prompt: fullPrompt,
            //             stream: true // 开启流式响应
            //         })
            //     });
            //
            //     if (!response.ok) {
            //         throw new Error(`请求失败,状态码: ${response.status}`);
            //     }
            //
            //     // 处理流式数据
            //     const reader = response.body.getReader();
            //     const decoder = new TextDecoder();
            //     let done = false;
            //     let currentResponse = '';
            //     while (!done) {
            //         const { value, done: readerDone } = await reader.read();
            //         done = readerDone;
            //         if (value) {
            //             const chunk = decoder.decode(value, { stream: true });
            //             // 解析 JSON 数据
            //             const lines = chunk.split('\n').filter(line => line.trim() !== '');
            //             for (const line of lines) {
            //                 try {
            //                     const data = JSON.parse(line);
            //                     if (data.response) {
            //                         // 更新响应文本
            //                         currentResponse += data.response;
            //                         this.responseText += data.response;
            //                     }
            //                 } catch (error) {
            //                     console.error('解析 JSON 数据时出错:', error);
            //                 }
            //             }
            //         }
            //     }
            //     // 将助手的回复添加到对话历史中
            //     this.conversationHistory.push({ role: 'assistant', content: currentResponse });
            // } catch (error) {
            //     console.error('请求出错:', error);
            // }
        }
    },
    template:`<div class="ollama-chat">
  <!-- 显示对话历史的区域 -->
<!--    <div class="history-area">-->
<!--      <div v-for="(item, index) in conversationHistory" :key="index" class="response-area">-->
<!--        <span :class="item.role === 'user' ? 'user-message' : 'assistant-message'">-->
<!--          {{ item.role === 'user' ? '用户: ' : '助手: ' }}-->
<!--        </span>-->
<!--        <span>{{ item.content }}</span>-->
<!--      </div>-->
<!--    </div>-->
<!--        <textarea v-model="inputText" placeholder="请输入问题"></textarea>-->
<!--    <button @click="sendRequest">发送请求</button>-->
<!--    -->
<!--    <div class="response-area">{{ responseText }}</div>-->
    
    <h1>Ollama Chat</h1>
    <div ref="scrollDiv" class="chat-history response-area">
      <div v-for="(message, index) in chatHistory" :key="index">
        <p><strong>{{ message.role === 'user' ? 'You' : 'Ollama' }}:</strong> {{ message.content }}</p>
      </div>
    </div>
    <input
      v-model="userInput"
      placeholder="Type your message..."
      @keyup.enter="sendMessage" style="width: 70%;padding: 5px;margin-right: 10px;"
    />
    
    <button @click="sendMessage">Send</button>
    <button @click="scrollToBottom">botom</button>
    <div class="chat-history response-area">{{ currentResponse }}</div>
</div>`
}
相关推荐
心易行者4 小时前
Python在线运行+SQLite数据库实战:0成本搭个人数据后台,5个场景直接套用
前端·网络·人工智能·python
雪芽蓝域zzs4 小时前
第 10 章:大屏看板自动轮播高亮(ECharts 大屏经典效果)
vue.js·echars
@tangguo1235 小时前
npm 和 yarn 配置说明
前端·javascript·npm·node.js·yarn
zhiyouTech5 小时前
GEO实战:把生成式引擎优化当成检索工程来做(含五断点诊断与50题Benchmark)
前端·人工智能
志尊宝5 小时前
Vue3 零基础每日笔记(052):路由常见坑一次排雷——404、刷新丢参数、部署白屏
前端·javascript·vue.js·笔记·html5
linux_cfan5 小时前
videojs v10 源代码系列解读:13 · 能力型媒体契约:`Media` 的组合接口
前端·javascript·音视频
涛涛ing5 小时前
2026年9月,前端圈同时发生了四件事,指向同一个方向
前端
艾伦野鸽ggg5 小时前
Vue2 模板语法与样式绑定
前端
Amos_Web5 小时前
Rspack 源码解析(十一):资产 Hook 与增量构建
前端·rust·源码阅读
PC2005_cloud5 小时前
Windows 数据使用量页面卡死:1097 个热点档案和 161 MB 的 SRUM 库
前端·后端