chatMed开发日志博客(持续更新中)

news2025/1/18 19:07:52

目录

1. 项目概述

2. 开发人员团队

3. 大致需求

4. 开发内容

4.1. 前端开发

4.1.1: 前端页面开发

4.1.2: 登录机制以及路由守卫的开发

4.1.3: 文件上传机制和保存机制

4.1.4: 消息传递机制'

4.2. 线程池开发

4.3. 在线调试


1. 项目概述

 搭建一个基于深度学习的分析平台, 使研究人员能够使用先进的深度学习架构, 来进行多模态医学影像的分析. 在完成模型多模态交互的同时, 为医护人员提供快捷便利的医学影响参考平台, 减轻医生的工作压力.

本项目采用人机交互设计原则和用户体验研究,设计了直观、简洁、易用的界面,并提供了个性化的用户操作,以增强医生和患则对系统的接受度和使用意愿。


本项目能处理多种不同模态的医学影像数据,如MRI、CT、X光等,以及临床数据,如患者的病史、症状等。有效地整合不同模态的信息,提取更丰富和准确的特征,进一步提高诊断和治疗的效果。


本项目通过多轮对话交互提供更有效的医学影像分析结果,支持病灶分割、疾病分类、病变检测以及疾病进展监测,为医生和患者提供了更好的医疗服务。


本项目能够解决百姓日常生活中大多数的医学问答、健康科普、健康管理等相关问题,采用自然语言处理技术和深度学习算法,通过大模型训练方法,形成人工智能“医生大脑”。

2. 开发人员团队

5人(tg, wyx, wyt, cjy, xpk), 分别负责开发, 测试以及产品设计等等工作.

3. 大致需求

搭建一个基于深度学习的分析平台, 使研究人员能够使用先进的深度学习架构, 来进行多模态医学影像的分析.

4. 开发内容

4.1. 前端开发

前端使用react架构实现开发, 最终预计在服务器环境上完成部署, 下方的目录顺序并非实际开发顺序, 每个部分均有所更新.

4.1.1: 前端页面开发

前端页面使用react开发, 采用组件式开发模式:

分成如图所示的多个界面, 最终效果如图所示:

内部功能如图所示:

4.1.2: 登录机制以及路由守卫的开发

首先先创建一个组件用来保存登录状态并将状态传递给下方的每一个组件, 在组件包括了跟组件

import { createContext, useState } from 'react';

export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [session, setSession]=useState('')
  const [email, setUserEmail]=useState('')

  const login = () => {
    setIsLoggedIn(true);
  };

  const logout = () => {
    setIsLoggedIn(false);
  };

  return (
    //传递数据为登录信息, 登入和登出操作, 会话id, 用户邮箱, 以及对应的修改操作
    <AuthContext.Provider value={{ isLoggedIn,login, logout,session,email,setUserEmail, setSession }}>
      {children} 
    </AuthContext.Provider>
  );
};

 将组件状态传递给下方的每一个组件

import logo from './logo.svg';
import './App.css';
import Home from './pages/home';
import { BrowserRouter, Routes,Route } from 'react-router-dom';
import Login from './pages/login';
import About from './pages/about';
import { AuthProvider } from './Auth';
import ProtectedRouter from './components/ProtectRouter';
import Chat from './pages/chat';
import Register from './pages/register';

function App() {
  return (
    <AuthProvider>{/*根组件用来传递状态和登录信息*/}
      <BrowserRouter>
        <Routes>
          <Route path='/' element={<Home/>} />
          <Route path='/login' element={<Login/>} />
          <Route path='/register' element={<Register/>} />
          <Route path='/chat' element={<ProtectedRouter Component={()=><Chat/>}/>}/>
          <Route path='/about' element={<ProtectedRouter Component={()=><About/>}/>}/>
        </Routes>
      </BrowserRouter>
    </AuthProvider>
  );
}

export default App;

在一些需要登录的路由上创建一个路由守卫组件, 该组件会检测到用户是否正在登录状态, 如果不是, 则会强制跳转到登录界面. 

import { useContext } from 'react';
import { Navigate } from 'react-router-dom';
import { BrowserRouter, Routes,Route } from 'react-router-dom';
import About from '../pages/about';
import { AuthContext } from '../Auth';

const ProtectedRouter = ({Component}) => { //传进来的对象以及其他的属性

  const { isLoggedIn } = useContext(AuthContext); //检查登录状态
  return (
        isLoggedIn ?  <Component/> :  <Navigate to={{ pathname: '/login' }} /> //如果已经登录了, 就展示情况
  );
};

export default ProtectedRouter;

4.1.3: 文件上传机制和保存机制

在最开始的时候尝试过使用单独组件封装的方式来实现文件的上传,

import { Upload, message } from 'antd';
import React from 'react';

function getBase64(img, callback) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
}

function beforeUpload(file) {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('You can only upload JPG/PNG file!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('Image must smaller than 2MB!');
  }
  return isJpgOrPng && isLt2M;
}

class Avatar extends React.Component {
  state = {
    loading: false,
  };

  handleChange = info => {
    if (info.file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }
    if (info.file.status === 'done') {
      // Get this url from response in real world.
      getBase64(info.file.originFileObj, imageUrl =>
        this.setState({
          imageUrl,
          loading: false,
        }),
      );
    }
  };

  render() {
    const uploadButton = (
      <div>
        <div className="ant-upload-text">Upload</div>
      </div>
    );
    const { imageUrl } = this.state;
    return (
      <Upload
        name="avatar"
        listType="picture-card"
        className="avatar-uploader"
        showUploadList={false}
        action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
        beforeUpload={beforeUpload}
        onChange={this.handleChange}
      >
        {imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
      </Upload>
    );
  }
}

export default Avatar 

 但是后续出现了很多问题, 所以改用原生来实现提交

 {(!imgUploaded) 
                      &&
                      //自定义一个文件输入框
                      <button style={{
                          border: 'solid 5px #284B63',
                          borderRadius: 100,
                          height: 60,
                          width: '100%',
                          color:'#284B63',
                          fontSize:20,
                          fontWeight: 700,
                          marginBottom:20

                      }} onClick={()=>chooseFile()}>choose File</button>
                  }
                  {/*文件上传按钮, 隐藏原始的文件输入, 然后自定义一个*/}
                  <input type="file" id="fileInput" accept="*" style={{margin:10,display:'none'}}/>
                  {/*图片展示*/}
                  {hasImg && <div  style={{height:256,width:256,justifyContent:'center',alignContent:'center'}}>
                    <img id="previewImage" alt="Preview" style={
                      imgUploaded?
                      {
                        height:256,
                        width:256
                        }
                      :
                      {
                        height:218,
                        width:218
                        }
                    }></img>
                  </div>}
                  {/*文件发送到后端的按钮*/}
                  {hasImg && (!imgUploaded) && <button onClick={()=>sendImage()} style={{
                          border: 'solid 5px #284B63',
                          borderRadius: 100,
                          height: 60,
                          width: '100%',
                          color:'#284B63',
                          color:'#284B63',
                          fontSize:20,
                          fontWeight: 700,
                          marginTop:20
                  }}>
                    Init dialog
                  </button>}
                </div>

 为了修改原有的ui按钮, 我们将原本的提交机制给隐藏, 再通过js进行点击事件的模拟触发, 最终实现图片的上传和展示, 图片的命名方式为img+会话id

//文件上传对象
    const fileInput = document.getElementById('fileInput');  
    //设置监听对象
    fileInput.addEventListener('change', (event) => {  
        const file = event.target.files[0];  
        const previewImage = document.getElementById('previewImage'); 
        if (file) {  
            if (file.type.startsWith('image/')) { 
              setHasImg(true)  
              const reader = new FileReader();  

              reader.onload = (e) => {  
                  // 读取完成后,数据URL会作为结果  
                  previewImage.src = e.target.result;  
              };  
                // 以Data URL的形式读取文件  
                reader.readAsDataURL(file);  
            } else {  
                alert('please choose a image file!');  
            }  
          }
        })

4.1.4: 消息传递机制'

消息传递大致为以下三种

指令序号内容
0启动对话并将会话id传递给前后端
1停止会话
2正常的通讯消息
3传递图片

前端的websocket数据监听

    const wsMessageHandler = (message) => {
      const data = jsonToObject(message.data);
      if (data.type === 0){ //后端返回一个登录状态
        setId(data.id); 
        setSession(data.id) //设置登录状态,知道会话id
      }
      else if (data.type === 1) {
        console.log('当前问诊已经结束');
      }
      else if (data.type === 2) {
        console.log('模型消息回复为', String(data.message));
        appendList(String(data.message)) //是这个的问题, 强制刷新消息
        setDialogShow(false)
      }
      else if (data.type === 3) {
        console.log('图片的存储地点为', data.url);
      }
    };

 后端ws数据监听

if(conn){                       //如果链接对象已经创建
            work=conn.worker            //获取线程链接

            if(data.type===2) {         //发送到ws的指令为2, 则把数据传下去
                work.postMessage(data)

            }else if(data.type===1){    //接收到1指令
                console.log('会话'+data.id+'已经停止')
                work.postMessage(data)  //向线程发送停止信息
                workers.delete(data.id) //从线程队列中删除会话

            }else if(data.type===3){    
                // 将Base64编码的字符串转换为Buffer
                const imageBuffer = Buffer.from(data.data.split(';base64,').pop(), 'base64');
                // 指定要保存图像的文件路径和文件名
                const imagePath = './imgs/img'+data.id+'.png';
                // 将图像数据写入文件
                fs.writeFile(imagePath, imageBuffer, (err) => {
                    if (err) {console.error('Error saving image:', err); return; }
                });
                // 将图片的保存地址传递给子进程
                work.postMessage({...data,url:imagePath})
            }
        }

后端监听子线程的消息

worker.on('message', (message) => {
        console.log(message)
        conn=workers.get(message.id)
        if(message.type===2){
            conn.getWebSocket().send(objectToJson(message))
        }else if(message.type===1){
            workers.delete(message.id) //从维护队列中删除
            conn.getWebSocket().send(objectToJson(message)) //将数据发送给前端
        }else if(message.type===3){
            conn.getWebSocket().send(objectToJson(message)) //将数据发送给前端
        }
    })

4.2. 线程池开发

为了更好的实现用户的隔离和资源管理, 我们使用线程池的方式来实现前端-后端-模型的交互, 再开始阶段, 我们使用脚本来代替模型的功能

# 导入模块
import sys
import time

# 循环接收用户输入并进行对话,直到接收到指令退出
# 模拟的是一个模型的功能
time.sleep(5)
sys.stdout.buffer.write("你好".encode('utf-8'))
while True:
    # 接收用户输入, 这里是一个组合方法
    user_input = input() 

    # 如果用户输入指令 "exit",则退出循环
    if user_input.strip() == "exit":
        print("Exiting conversation...")
        break

    # 模拟数据的发送
    time.sleep(5)

    # python的回答, 也就是我们所需要的诊断内容, 果然是把这一句直接ASCII化了
    sys.stdout.buffer.write("模型输出".encode('utf-8'))

后端主页代码

const WebSocket = require('ws');
const { Worker } = require('worker_threads');
const {jsonToObject,objectToJson,generateUniqueId}=require('./tool.js')
const fs = require('fs');

// 创建 WebSocket 服务器, 该服务器监听的是3001端口
const wss = new WebSocket.Server({ port: 3001 });

//链接类,id, 和前端的链接ws, 和后端的链接worker
class Connection {
    constructor(id, ws, worker) {
        this.id = id;
        this.ws = ws;
        this.worker = worker;
    }
    getId() {  return this.id;  }
    getWebSocket() {   return this.ws;  }
    getWorker() { return this.worker;}
    setWebSocket(ws) {  this.ws = ws;}
    setWorker(worker) { this.worker = worker;}
}

//进程管理对象队列(映射)
const workers=new Map();


// 监听每次创建一个新的链接, 就会
// 创建一个ws对象并且设置监听器
// 将其加入队列中
wss.on('connection', (ws) => {
    //创建id
    const id=generateUniqueId()
    
    //生成链接对象并且创建监听
    ws.addEventListener('open', () => {
        console.log('WebSocket connection established');
    });
    //监听前端的信息
    ws.addEventListener('message', (event) => { 
        data=jsonToObject(event.data)
        conn=workers.get(data.id)   //先判断该会话是否还存在, 如果不存在就不需要什么反应
        if(conn){                       //如果链接对象已经创建
            work=conn.worker            //获取线程链接

            if(data.type===2) {         //发送到ws的指令为2, 则把数据传下去
                work.postMessage(data)

            }else if(data.type===1){    //接收到1指令
                console.log('会话'+data.id+'已经停止')
                work.postMessage(data)  //向线程发送停止信息
                workers.delete(data.id) //从线程队列中删除会话

            }else if(data.type===3){    
                // 将Base64编码的字符串转换为Buffer
                const imageBuffer = Buffer.from(data.data.split(';base64,').pop(), 'base64');
                // 指定要保存图像的文件路径和文件名
                const imagePath = './imgs/img'+data.id+'.png';
                // 将图像数据写入文件
                fs.writeFile(imagePath, imageBuffer, (err) => {
                    if (err) {console.error('Error saving image:', err); return; }
                });
                // 将图片的保存地址传递给子进程
                work.postMessage({...data,url:imagePath})
            }
        }
    });

    //将id, 链接对象和子线程组合存储, 其中ws代表前端, worker代表后端线程
    ws.addEventListener('error', (error) => {
        console.error('WebSocket error:', error);
    });
    ws.addEventListener('close', () => {   //监听到链接关闭以后
        console.log('用户页面已经关闭')     //将ws直接删除掉
        conn=workers.get(id)   
        if(conn){              
            workers.delete(id)
        }
    });

    // 创建子线程
    const worker=new Worker('./worker.js')
    // 监听来自子线程的消息
    worker.on('message', (message) => {
        console.log(message)
        conn=workers.get(message.id)
        if(message.type===2){
            conn.getWebSocket().send(objectToJson(message))
        }else if(message.type===1){
            workers.delete(message.id) //从维护队列中删除
            conn.getWebSocket().send(objectToJson(message)) //将数据发送给前端
        }else if(message.type===3){
            conn.getWebSocket().send(objectToJson(message)) //将数据发送给前端
        }
    })

    //前端链接, 线程链接, 以及id存储起来
    workers.set(id, new Connection(id,ws,worker))

    //发送给前端id信息
    ws.send(objectToJson({type:0,id:id}))
    //发送给子线程id信息
    worker.postMessage(objectToJson({type:0, id:id}))
    
    console.log('新增会话用户, 当前会话数目为', workers.size)

});

子线程管理代码

// worker.js
const { parentPort } = require('worker_threads');
const {jsonToObject,objectToJson}=require('./tool');
const { spawn } = require('child_process');

/*
主线程会根据worker.js中的代码创建一个子线程
创建子线程的同时, 启动一个python服务, 该服务在启动的时候, 就把图片数据和第一个prompt传递过去
*/

//问诊状态
let inquiried=false
//图片地址
let imgUrl=''
// python脚本执行对象
let  pythonProcess;
//会议id
let id;


//开启问诊状态,参数为图片的地址
//传递的msg就是图片的地址================================================================
const startInquriy=(msg)=>{
    //启动模型,
    pythonProcess = spawn('python', ['./foot.py', msg, '请你帮我诊断这张图片' ], {   
        stdio: ['pipe', 'pipe', 'pipe'] ,
        encoding: 'utf-8'
    });
    //为模型增加一个输出监听, 从此会开始监听模型的输出
    pythonProcess.stdout.on('data', (data) => {
        if(!inquiried){
            //如果检测到这是第一次输出, 则开启问诊状态
            inquiried=true
            //先进行响应3,告知前端图片地址在什么地方
            parentPort.postMessage({type:3, id:id, url:msg})
        }
        //响应2, 告知前端模型的意见
        // 将Buffer对象转换为十六进制字符串,并使用正则表达式替换掉空格
        const hexString = data.toString('hex').replace(/ /g, '');
        console.log(Buffer.from(hexString, 'hex'))
        // 将十六进制字符串转换为实际的字符串
        const str = Buffer.from(hexString, 'hex').toString('utf-8');
        console.log(str)
        parentPort.postMessage({type:2, id:id, message:str})
    });
}

// 向 Python 脚本发送数据, 参数为发送的数据
const sendDataToPython = (data) => {
    pythonProcess.stdin.write(data + '\n'); // 在每条消息末尾加上换行符
};


// 监听主线程发送的消息
parentPort.on('message', (message) => {
    data=message
    //0指令, 给线程分一个id
    if(data.type===0){
        id = data.id;
    }
    //1指令, 线程停止
    else if(data.type===1){
        if(inquiried){ 
            //停止python脚本
            sendDataToPython('exit');
            //停止线程
            process.exit()

        }
    }
    //2指令, 发来数据, 传回数据
    else if(data.type===2){
        //输入数据, 这个data.message其实就是前端传入进来的话
       if(inquiried){ 
            sendDataToPython(data.message);
        }
    }
    //3指令, 开启对话
    else if(data.type===3){
        //输入图片, 并且确认开启python脚本
        imgUrl = data.url
        id = data.id
        startInquriy(data.url);
    }
});



4.3. 在线调试

在线调试的过程中遇到cors跨域的问题, 解决方案是使用http-server的包进行本地服务器建立并且运行, 在目录下进入启动http-server指令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719896.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scrapy vs. Beautiful Soup | 网络抓取教程 2024

网络爬虫是任何想要从网上收集数据用于分析、研究或商业智能的人必备的技能。Python中两个最受欢迎的网络爬虫工具是Scrapy和Beautiful Soup。在本教程中&#xff0c;我们将比较这些工具&#xff0c;探索它们的功能&#xff0c;并指导你如何有效地使用它们。此外&#xff0c;我…

国产FPGA核心板!米尔紫光同创Logos-2和Xilinx Artix-7核心板

随着嵌入式的快速发展&#xff0c;在工控、通信、5G通信领域&#xff0c;FPGA以其超灵活的可编程能力&#xff0c;被越来越多的工程师选择。近日&#xff0c;米尔电子发布2款FPGA的核心板和开发板&#xff0c;型号分别为&#xff1a;基于紫光同创Logos-2系列PG2L100H的MYC-J2L1…

Linux基础指令及其作用之系统信息和管理

系统信息和管理 ps ps 命令用于显示当前系统的进程信息。它是 Unix 和类 Unix 操作系统中的一个重要工具&#xff0c;可以用于监控和管理系统进程。以下是 ps 命令的详细用法和常见选项&#xff1a; ps [选项]常用选项![在这里插入图片描述](https://img-blog.csdnimg.cn/di…

从摇一摇到弹窗,AD无处不在?为了不再受打扰,推荐几款好用的屏蔽软件,让手机电脑更清爽

当我们沉浸在智能手机带来的便捷与乐趣中时&#xff0c;内置AD如同不速之客&#xff0c;时常打断我们的体验。 尤其是手机上那些“摇一摇”跳转&#xff0c;稍有不慎就会跳转到其他应用&#xff0c;令人不胜其烦。同样&#xff0c;电脑上的内置AD也如影随形&#xff0c;影响了我…

深度学习模型的C++部署:ONNXRUNTIME引领跨平台革命

一、引言 在AI技术的浪潮中&#xff0c;深度学习模型的部署已成为工程师们的核心技能。随着AI技术的不断进步&#xff0c;对于能够高效部署模型的人才需求日益增长。C因其在性能和系统级控制方面的优势&#xff0c;正逐渐成为深度学习模型部署的行业新宠。 二、C&#xff1a;…

【介绍下运维,什么是运维?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

【Qt】【模型-视图架构】代理模型示例

文章目录 1. 基本排序/过滤模型Basic Sort/Filter Model Example2. 自定义排序/过滤模型Custom Sort/Filter Model ExampleFilterLineEdit类定义及实现MySortFilterProxyModel类定义及实现 1. 基本排序/过滤模型Basic Sort/Filter Model Example 官方提供的基本排序/过滤模型示…

liunx文件系统与日志分析

文章目录 一、基本概念二、日志分析三、实验 一、基本概念 文件是存储在硬盘上的&#xff0c;硬盘上的最小存储单位是扇区每个扇区大小事512字节 inode&#xff1a;元信息&#xff08;文件的属性 权限 创建者 创建日期&#xff09; block&#xff1a;块 连续八个扇区组成一块…

Selenium Server 中 Standalone 模式|实现分布式测试、远程驱动浏览器

实现分布式测试|远程驱动浏览器 Selenium Server 介绍主要功能 Standalone 模式概括Standalone 模式分布式测试的应用 Selenium Server 介绍 Selenium Server 是 Selenium 自动化测试框架的核心组件之一&#xff0c;负责管理和控制浏览器,为测试脚本提供底层支持 主要功能 浏…

麒麟系统 安装xrdp 远程桌面方法记录

一、安装环境 麒麟V10 2107 ft2000 麒麟V10 2107 x86_64 二、安装准备 使用《Kylin-Desktop-V10-Release-2107-arm64.iso》镜像 做好U盘启动系统后&#xff0c;需要安装一个远程桌面工具&#xff0c;可以多用户在windows上使用远程桌面访问麒麟系统。 目前在linux系统上较…

Conditional DETR解读---带anchor的DETR

DETR存在的问题 1.收敛速度慢 2.对小目标物体检测效果不好&#xff0c;因为transformer计算量大&#xff0c;受限于计算规模&#xff0c;CNN提取特征时只采取了最后一层特征&#xff0c;没有用FPN等结构。所以对于小目标检测效果不好。 论文主要观点 通过对DETRdecoder中的a…

Java—— StringBuilder 和 StringBuffer

1.介绍 由于String的不可更改特性&#xff0c;为了方便字符串的修改&#xff0c;Java中又提供了StringBuilder和Stringbuffer类&#xff0c;这两个类大部分功能是相同的&#xff0c;以下为常用方法&#xff1a; public static void main(String[] args) {StringBuilder sb1 n…

乡村振兴与乡村旅游创新:创新乡村旅游产品,提升旅游服务水平,打造特色乡村旅游品牌,助力美丽乡村建设

目录 一、引言 二、乡村旅游产品的创新 &#xff08;一&#xff09;挖掘乡村特色资源 &#xff08;二&#xff09;注重产品体验性 &#xff08;三&#xff09;创新旅游产品形态 三、旅游服务水平的提升 &#xff08;一&#xff09;加强基础设施建设 &#xff08;二&…

微信小程序-页面导航-导航传参

1.声明式导航传参 navigator组件的url属性用来指定将要跳转到的页面的路径&#xff0c;同时&#xff0c;路径的后面还可以携带参数&#xff1a; &#xff08;1&#xff09;参数与路径之间使用 ? 分割 &#xff08;2&#xff09;参数键与参数值用 相连 &#xff08;3&…

《SpringBoot3+Vue3实战》系列文章目录

前后端分离&#xff08;Frontend-Backend Separation&#xff09;是一种软件架构设计模式&#xff0c;它将传统的Web应用中的前端&#xff08;用户界面&#xff09;和后端&#xff08;服务器逻辑和数据存储&#xff09;从应用层面进行解耦&#xff0c;使得两者可以独立地开发、…

conda与pip的镜像源与代理设置

conda与pip的镜像源与代理设置 一、前言二、conda镜像源设置2.1conda默认镜像源介绍2.2通过终端设置镜像源2.3通过配置文件设置镜像源 三、pip镜像源设置3.1pip默认镜像源介绍3.2通过终端临时设置镜像源3.3通过配置文件设置一个或多个镜像源 四、conda代理设置4.1通过终端设置代…

铁塔基站用能监控能效解决方案

截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5G基站的能耗成为…

【论文速读】Self-Rag框架,《Self-Rag: Self-reflective Retrieval augmented Generation》

关于前面的文章阅读《When to Retrieve: Teaching LLMs to Utilize Information Retrieval Effectively》&#xff0c;有网友问与Self-Rag有什么区别。 所以&#xff0c;大概看了一下Self-Rag这篇论文。 两篇文章的方法确实非常像&#xff0c;Self-Rag相对更加复杂一些。 When …

大模型部署_书生浦语大模型 _作业2基本demo

本节课可以让同学们实践 4 个主要内容&#xff0c;分别是&#xff1a; 1、部署 InternLM2-Chat-1.8B 模型进行智能对话 1.1安装依赖库&#xff1a; pip install huggingface-hub0.17.3 pip install transformers4.34 pip install psutil5.9.8 pip install accelerate0.24.1…

系统架构设计师【第5章】: 软件工程基础知识 (核心总结)

文章目录 5.1 软件工程5.1.1 软件工程定义5.1.2 软件过程模型5.1.3 敏捷模型5.1.4 统一过程模型&#xff08;RUP&#xff09;5.1.5 软件能力成熟度模型 5.2 需求工程5.2.1 需求获取5.2.2 需求变更5.2.3 需求追踪 5.3 系统分析与设计5.3.1 结构化方法5.3.2 面向对象…