lora微调笔记

微调笔记

分类:

fine tuning 传统全量微调,(高质量微调)

prompt tuning(提示词微调)

​ 技术:指令微调

​ 上下文学习

​ chain of thought(思维链)

PET模型(Pattern-Exploiting Training)

POFT方法:分成三种类型:(面向提示的微调)

  • 全量微调(Full Fine-Tuning):模型所有参数都参与更新,包括预训练模型参数和下游任务层参数。如PET模型。
  • 部分参数微调(Partial Fine-Tuning):只更新预训练模型中的一部分参数,比如高层 transformer block、某些 attention 层或特定模块,其余参数冻结。如Adapter Tuning。
  • 仅提示参数微调(Prompt-Only Tuning):冻结原始预训练模型参数,只训练 prompt 参数。如P-tuning、Prompt Tuning等。

Soft Prompt及微调方法

PEFT(参数高效微调)

conda env export > /ptune_chatglm/execute_successful_requir.txt

autodl-tmp/llm_tuning/ptune_chatglm

LoRA

三元组提取(基于用户的输入prompt,送给大模型,做实体提取预测。)

文本分类

问题:

请基于这个html文件,告诉我这是什么任务,基于用户评论的情感分类吗?

lora_rank中lora的每个单词是什么意思

THUDM是什么意思?是组合缩略词吗?拆解开来是哪些单词组成的。合起来是什么意思。尤其在代码中是什么意思?

done


谷歌浏览器的添加网页功能很单一,加到一定数量之后,一些网址就隐藏到可视列表之下了,需要滚轮向下翻。我想知道如何把这些添加的网页管理起来,把相似的网页,放到同一个目录下。

请基于上传的两个html文件,告诉我data_process.py文件中,读取的数据

请告诉我在json文件中 \n和\n\n符号的区别?

{“context”: “Instruction: 你现在是一个很厉害的阅读理解器,严格按照人类指令进行回答。\nInput: 句子中包含了哪些信息,输出json:\n\n江立,男,瑶族,1978年1月出生,广西恭城人。\nAnswer: “, “target”: “json\n[{\"predicate\": \"出生日期\", \"object_type\": \"Date\", \"subject_type\": \"人物\", \"object\": \"1978年1月\", \"subject\": \"江立\"}, {\"predicate\": \"民族\", \"object_type\": \"Text\", \"subject_type\": \"人物\", \"object\": \"瑶族\", \"subject\": \"江立\"}, {\"predicate\": \"出生地\", \"object_type\": \"地点\", \"subject_type\": \"人物\", \"object\": \"广西恭城\", \"subject\": \"江立\"}]\n“}

上述句子中句尾\n后的三撇是什么符号?

pandoc “D:\software\fine_tuning\01_课件\site\01-大模型微调主要方式\01-大模型Prompt-Tuning方法.html” -f html -t markdown –wrap=preserve -o “C:\Users\gan\Desktop\输出文件.md”

批量转换(在 PowerShell 中):
打开 PowerShell,导航到你的 HTML 文件所在的文件夹,然后运行:

powershell

复制

下载

1
Get-ChildItem *.html | ForEach-Object { pandoc $_.Name -f html -t markdown -o ($_.BaseName + ".md") }

1
nvidia-smi 查看cuda版本号

1756116507220

RAG流程

RAG流程:

mysql储存FQA高频问答对数据

问题检索:BM25

连接数据库

添加表(带着字段)

添加数据

json.dumps()

mysql 存储自己的网址和密码。(自己设计一个RAG系统)

声明回退问题,把原来的复杂查询简化,第一个query检索

进行改写。主题含义不变。

milvus可以处理的数据集的大小限制是多少

技术实现:

增强索引:设计目标、核心功能、技术实现

多粒度切块,把块-分子块,对应的父块,提供给LLM

文档切成一块,存储milvus中的文档,

query是为题,编程向量,

太长的拆成四个

128个向量

父块是一个

子块分成子块去做检索

切块的子块数都是超参数

混合检索:BM25,向量检索,字符检索

base:基础模块,配置、日志

core:核心逻辑模块,实现RAG的关键功能

main:系统运行入口,支持数据处理和交互查询

中午将一份唯二

通用知识由大语言模型回答,

直接 hyde 子查询 会输

文档检索:支持抽向量和系数向量的混合检索,

中午,下午

语义关键字,倒排(关键字检索

两句话的相似性,

混合检索,重排序优化,

作为回答送给大模型,方便理解。

用户查询

代码目录结构:

配置管理、日志记录

config。py

最大支持customer service phone

fallback

document_process

langchain的文档加载器

markdowm text splitter

datetime import datetime

相对路径(三方包)

模型切分工具、

文档加载器的类(处理pdf、word、ppt、图片

OCR可以提取图像里的内容

optical character recognition光学字符识别

paddle paddle ocr的工具库,基于深度学习技术,

可以把图像中的文字提取出来。

pdf 中的图片,怎么解决?paddle OCR;只能识别简单的图片rapid OCR

cv2:

寻味羊*村超BA之苗侗味道(第一档口华兴美食城店)

docx第三方库

迭代器

读取ppt的内容OCRIMGLoader(file path)

添加源数据,direcotry_path

documents 所有的键

扩展名集合

source

RAG-Langchain

RAG-Langchain

RAG

解决什么问题:

信息过时:网络检索,获取最新数据

领域知识缺失:微调,将专有和私有的知识放到知识库里

幻觉:RAG(retrieval augmented generate),减轻幻觉,基于相关文档进行生成,

安全:RAG,无需将数据送到公开大模型中训练,放到本地知识库,使用本地的模型(api会泄露)进行调用,避免数据的公开和泄露。2)私有数据时存在本地知识库的,做一个权限的管控。

RAG定义:检索技术+生成(LLM提示)

处理流程:构建索引(文件加载、内容读取、chunk构建(拆成小文件,小块)、向量化(小块文档向量化)、落向量化

检索:query向量化,找到topk

生成:topk+query构建prompt;llm生成。

开发框架:LLaMAIndex、Langchain(快速搭建大模型)

Langchain

langchain将模型分为三种(

langchian是用于构建大模型应用程序的框架,帮助开发者更高效的组合和使用多语言的工具。

原始大模型:LLM、chat models、embeddings

chain:组装chain:chain=LLMChain(llm=model,prompt=prompt_template)

output_parsers

字符串解析器、列表解析器、json解析器、定义类、自定义解析器

根据实际情况,调用api,做规范化

字符串解析器:提取模型返回的原始文本

1
2
3
4
5
6
7
8
9
创建简单链
创建字符串解析器
stroutputparser()
组合组件
prompt|model
调用链
result=chain.invoke()
将字符串解析器添加到链中

列表解析器:文本转换为列表

parser.get format instructions 创建带格式说明的提示模版

1
2
3
创建列表解析器
创建提示模版,包含列表解析器的格式说明,也就是你要告诉模型输出的格式,然后大模型会按照这个输出结果

Json解析器

1
2
3
创建带格式说明的提示模版
json.parse.geet_format_instructions()
Chatprompttemplate.from_template()

Pydantic解析器:python库,用于数据验证

1
2
3
4
5
定义pydantic模型
创建pydantic解析器
创建带格式说明的提示模版
组合组件
调用链

自定义解析器(输出格式非常复杂情况下,就自定义格式进行输出)

1
2
3
4
5
6
7
8
需要继承baseoutputparser,实现parse()方法,get format instructions()方法
解析大模型的输出,然后组织成想要的个数
提供格式指导给模型
处理空白和换行符,用冒号做split切分;返回一个字典
custom,
定义大模型输出的格式
from template(模版说明)

解析器:告诉大模型该怎么输出 get_fromat_instructions()

invoke(填充好提示词),最后通过结果解析器,调用parse方法

核心是实现parse方法。

Memory

储存上下文,储存历史

langchain提供了memory组件:

ChatMessageHistory:只是简单存储

1
2
3
4
5
6
history = ChatMessageHistory()
添加用户消息
history.add_user_message('xxx')
添加大模型回复的消息
history.add_ai_message('xxx')

ConversationChain:

创建一个对象,放一个llm=llm参数

1
2
3
4
5
6
7
8
9
实例化一个对象,传一个大模型
model = ChatTongyi(model='',temperature=3000)
实例化会话链,这里需要传入模型
conversation=ConversationChain(llm=model)
conversation.predict(input='123')
conversation.predict(input='456')
conversation.predict(input='一共有几个数字')
print(result)
conversation自动维护上下文信息

indexes

让langchain具备处理文档处理的能力,包括文档加载、检索、文档加载器、文本分割器、vectorstores、检索器。

文档加载器

1
2
3
4
5
6
7
8
9
10
11
12
引入loader工具
初始化对象
loader = UnstructureLoader('./data/衣服属性.txt,encoding='utf8')
加载数据到内存中(返回值是一个列表,每一个元素是一个document对象,对应原文件的一行数据
docs = loader.load
print(f'len-->{len(docs)}')
打印第一行数据
docs[0].page_content
langchian_community:证明是三方写的包(相比之下,三方打印更简洁了)
from langchian_community.document.loader import Textloader
textloader返回值是一个列表,每一个元素是一个document对象,对应原文件的所有数据

文档分割器:分割字符,按照字符长度

chunk_size= 多少数量切一块;chunk_over=重叠字符数;separator=按照分割符进行切割。既可以制定分隔符。

e.g.假设chunk size=500;chunk over=0;separator=句号;文本中有五个句子。第一个句子100个字符,第二个句子200个字符,第三个句子100;不超过500,则以上三个句子打包成一个chunk。但是第四个句子是200个字符。则放弃第四个句子。第四放到第二个chunk中

1
2
3
4
5
6
7
langchain.text.splitters import CharacterTextSplitter
创建分词器separator参数指的是分割的分隔符,chunk size指的是分割出来的每个块的大小,chunk overlap是指每个块之间重复的大小
CharacterTextSplitter(separator="",chunk_size=5,chunk_overlap=0)
一句话进行分割
text_splitter.split_text('a b c d e f')
多句话分割(传一个可迭代对象,列表)
text_splitter.create_documents('a b c d e f','e f g h')

缺点:

按数量进行切割,无法保存完整语义

如果读取的文档中某一段分隔符缺失,或者长段句子没有分隔符,则依旧存在句子过长的问题

只适合简单文本,不适应复杂文本

递归字符文本分割器

可以使用多个分隔符,依次使用分隔符,知道长度满足要求为止

separators=[‘\n\n’,’\n’,’ ‘]

语义文档分割器

基于语义相似性分割文本

计算成本较高,

适用于需要高度语义理解的场景(文档比较重要的情况,网页爬取就不需要了)

embedding文本之后,判断语义相似性。

字符-递归-语义(随复杂和重要程度递增)

其他专用分割器(MarkdownHeaderTextSplit)

按照你的章节去做切割,一章内大概都是一个意思

先实例化对象

markdown_spliter=MarkdownHeaderTextSplitter()

markdown_text=

docs = markdown_splitter.split_text(markdown_text)

再用对象去做切割

自定义分割器

chains回顾

连接LLM与其他组件,完成应用程序的开发过程

MESS

导演名称,年份、信息对称,返回的结果,使用dantic,从结果中提取出来。就是这个结果。看齐的类型。

字符分割器(characterTextSplitter)

字符分割器是基于,按照空格进行切分。按照指定的数量,递归字符文本分割器(recursive character textsplitter)

递归字符文本分割器是一种更智能的分割方法,它尝试在特定分割符处分割文本,以保持更好的语义完整性。

特点:

尝试在自然断点处分割文本

比简单的字符分割更能保持语义完整性

适用于结构化成都较高的文本,如markdown、html

运行流程:

首先尝试使用第一个分隔符(如“\n\n”)分割文本

如果分割后的快任然过大,则使用给下一个分割符继续分割

重复此过程,知道达到指定的chunk_size或则用完所有的分隔符

语义文档分割器:更高级的分割方法

基于语义相似性分割文本

能够更好地保持语义完整性

计算成本较高,处理大量文本时可能效率较低

使用于需要高度语义理解的场景

其他专用分割器

如markdownHeadTextSplitter

文本分割参数调优策略

chunk size

chunk overlap

separator参数

非文本

sql lite(在本地存一个文件)

similarity search查询相应的文档

检索器

vectordb.similarity_search()用途:直接调用向量数据库的相似度搜索功能。输入:查询字符串(query)和可选的返回数量(k)。输出:按相似度排序的文档列表。

其他应用领域包括:

1、语义搜索系统

2、推荐系统

3、文档聚类

4、异常检测

5、多模态系统

6、内容去重

7、知识图谱

8、情感分析:捕捉文本的(情感特征)

检索器的功能和vectordb.similarity_search()相似;

调用检索器的方法:具体实现方式不一样。

可以封装到langchain的chain里面。

检索器是langchain中负责信息检索的模块,通常与索引(indexes)模块(如向量存储、文档加载器)结合使用。它的核心功能是:

输入:接受用户查询(文本)

处理

输出:返回一组相关文档或文本片段

工作流程:

查询嵌入

相似性搜索

文档返回

后处理:对查询结果做一些加工,(返回k个文档,对k个文档进行排序、过滤或重新排名)

检索器的核心依赖:

嵌入模型:

向量储存:

相似性度量:

similarity:精确匹配;最相关的k个做一个返回

mmr:平衡相关性和多样性;返回k个;生成综合性报告

similarity score threshold 质量过滤; 动态数量; 不控制多样性;高精度筛选;

lambda_mult:控制多样性(仅MMR搜索有效)

vectordb as_retriever()

返回一个retriever对象,用于langchain链式调用

tf-idf retriever

MULTIQUERYRETRIEVER

Contexttual

使用语言模型查询,生成多个解锁器。

ensembel retriever

查询依旧,但是检索不唯一。两种,或者以上。向量检索,达到非常好的效果。

向量检索的好。

custom retriever 生成多个查询语句,不同方式进行检索。把三种方法结合起来,进行使用。在里面实现。集成base retriever。看看试验方式,retriever;企业里常见的是混合优化,结构化优化。

Agent

Agent是一种能够感知环境、进行决策和执行动作的智能实体。不同于传统的人工智能,Agent具备通过主动思考、调用工具去逐步完成给定目标的能力。

外部工具,保存语义理解和推理能力,任务规划能力

a=大模型+任务规划+执行(调用外部工具)+记忆

大脑、五官、四肢

点菜(任务是找吃的);agent不知道,会调用美团、大众点评的api去搜附近美食,

自动给你点菜;最后在“付款”步骤,介入人工,避免支付风险。

用户提出任务:“agent启动;将输入和提示词模版结合,送给大模型

2、思考决策:大模型接受输入后,根据内置逻辑和提示词指导,进行思考

判断需要更多东西

是否需要工具

工具执行

结果反馈

循环

如果回答:当大模型判断任务已完成,无需额外工具即可回答时,它会生成最终的答案。

反思、自我批评、思考链、子任务分解

planning是计划,调用方法(搜索、调度、计算器的方法),完成规划里的任务

Action(一些需要调用,一些不需要调用外部工具)

先想(planing)再做;(循环);再思考过程中,会产生上下文(放到memory里面)

任务规划(planning);思考用户交代的任务

长短期记忆(memory):聊天上下文,长期保留和回忆信息

langchain实现智能体

langchain提供了不同类型的代理(主要罗列了三种:)

zero-shot-react-description:代理使用react框架,仅基于工具的描述来确定

structured-chat-zero-shot-react-description结构化的参数输入

conversational-react-description:上下文保存到记忆里面。

agent_toolkits.load_tools import load_tools

from langchain.agent import initialize_agent

tools,llm,agenttype.zero_shot_react_description,verbose=True

提示词传入

agent.invoke()

initialize_agent(tools,model,agent_type.ZERO_SHOT_REACT_DESCRIPTION,VERBOSE=TRUE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1、实例化大模型:
chatTongyi(model=‘qwen-max)
2、设置工具:
load_tools(wikipedia,llm-math,llm=model)
3、创建代理
initialize_agent(tools,model,agent_type.ZERO_SHOT_REACT_DESCRIPTION,VERBOSE=TRUE)
4、设置提示词并进行agent调用
prompt =
result = agent.invoke(prompt)
print(f'result-->{result})
思考过程:思考-动作(循环)
finished chain
result-->

总结:

什么是langchain?本质是一个框架(目的是快速的智能应用的开发)

组件

models(嵌入模型(embedding model)、普通大模型、聊天大模型)

prompt(普通prompt、chatprompt)

chains(chain、LCEL)

output parsers(字符串解析器、列表解析器、json解析器、pydantic解析器)

memory(保存上下文信息,conversationchain..

indexes(文档加载器、文档分割器、向量存储)

检索器(基于问题,在知识库中检索出对应的答案)

Agent(智能体是什么?)

Python调用Ollama平台本地部署QWen大模型API实现聊天机器人

今日目标

  • 掌握Ollama模块实现
  • 熟练使用Streamlit
  • 掌握基于Ollama平台Python语言聊天机器人实现

【熟悉】阿甘智聊机器人

项目介绍

随着人工智能技术的飞速发展,聊天机器人在多个领域得到了广泛应用,如客户服务、教育辅导、娱乐互动等。然而,现有的许多聊天机器人依赖于云端服务,这不仅可能导致用户数据隐私泄露,还可能因网络延迟影响用户体验。因此,开发一款本地部署的聊天机器人显得尤为重要。本地聊天机器人能够在用户本地环境中运行,确保数据的安全性和对话的实时性,同时也能根据用户的个性化需求进行定制和优化。

项目演示

1741522273918

项目技术架构

  • 后端模型:利用 Ollama 平台的 Qwen 模型,该模型具备出色的自然语言处理能力,能够理解和生成自然语言文本,为聊天机器人提供核心的对话处理功能。

  • 前端界面:采用 Streamlit 框架搭建用户界面,Streamlit 是一个简单易用的 Python 库,能够快速创建美观、交互式的 Web 应用,使用户能够通过网页与聊天机器人进行实时对话。

  • 对话交互:用户可以通过 Streamlit 界面输入文本,聊天机器人基于 Qwen 模型对输入内容进行理解和处理,生成相应的回复并展示在界面上,实现流畅的对话交互。

  • 模型调用:后端服务负责将用户输入传递给 Qwen 模型,并获取模型生成的回复,然后将回复内容返回给前端界面进行展示,确保对话的实时性和准确性。

  • 界面展示:Streamlit 界面提供简洁明了的布局,包括输入框、发送按钮和对话展示区域,用户可以方便地输入问题并查看机器人的回答,提升用户体验。

项目开发环境

  • 操作系统:支持主流操作系统,如 Windows、macOS 和 Linux。
  • 依赖软件:需要安装 Python 环境以及 Ollama 平台和 Streamlit 库。
  • 硬件要求:推荐配置较高的处理器和足够的内存,以确保模型的高效运行和良好的用户体验。

【熟练】Ollama模块实现

学习目标

能够使用Python调用本地部署大模型API,完成聊天对话功能

Qwen模型PythonAPI实现文本扩写

需求:通过python调用API实现基于qwen2在0.5b数据集下实现对文本的续写,用户输入一个简短的故事开头,系统能够生成一段连贯、有趣的续写内容。

细节: 本地需要先安装下依赖包.

pip install ollama

pip install langchain -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install langchain-community -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install dashscope -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install streamlit==1.32.0

1
2
3
4
import ollama
response = ollama.chat(model='qwen2:0.5b',messages=[{'role': 'user', 'content': '从前有座山,山里有个庙,庙里有个和尚叫二等兵下士阿甘,续写一下', },])
print(response.message.content)
print(response['message']['content'])

Qwen模型PythonAPI实现文本问答

需求:构建一个简单的命令行交互程序,用户可以通过输入问题与AI模型进行对话。该程序将使用qwen2:0.5b语言模型。用户可以通过命令行输入问题,程序将调用AI模型生成回答,并将结果输出到终端。

1
2
3
4
5
6
7
8
9
10
11
import ollama
# 3. 定义一个循环
while True:
# 4. 获取prompt提示词
prompt = input("请输入您的问题:")
response = ollama.chat(model='qwen2:0.5b',
messages=[{'role': 'user', 'content': prompt, }, ])
# 5. 调用模型,回答问题
result = response['message']['content']
# 6. 打印回答
print(result)

Qwen模型PythonAPI实现编程代码

需求:构建一个基于AI模型的代码生成工具,用户可以通过输入自然语言描述所需功能,AI模型将自动生成相应的Python代码。该工具旨在帮助开发者快速获取代码片段,减少手动编写代码的时间。

1
2
3
4
5
6
7
8
9
10
11
12
# 4. 获取prompt提示词
prompt = """
请为以下功能生成一段Python代码:
求两个数的最大公约数
"""
response = ollama.chat(model='qwen2:0.5b',
messages=[{'role': 'user', 'content': prompt}, ])
# 5. 调用模型,回答问题
result = response['message']['content']
# 6. 打印回答
print(result)

Qwen模型PythonAPI实现情感标签

需求:构建一个基于AI模型的用户反馈分类工具,用户可以通过输入具体的反馈内容,AI模型将自动将其归类到预设的类别中(如“价格过高”、“售后支持不足”、“产品使用体验不佳”、“其他”)。该工具旨在帮助企业快速分析用户反馈,识别主要问题,并采取相应的改进措施。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 4. 获取prompt提示词
prompt = """
你需要对用户的反馈进行原因分类。
分类包括:价格过高、售后支持不足、产品使用体验不佳、其他。
回答格式为:分类结果:xx。
用户的问题是:性价比不高,我觉得不值这个价钱。
"""
response = ollama.chat(model='qwen2:0.5b',
messages=[{'role': 'user', 'content': prompt}, ])
# 5. 调用模型,回答问题
result = response['message']['content']
# 6. 打印回答
print(result)

小结

  • 能够使用Python调用本地部署大模型API,完成聊天对话功能
    • 掌握基于Ollama平台调用Qwen模型
      • 文本扩写
      • 文本问答
      • 编程代码
      • 情感标签

【熟练】Streamlit

学习目标

实现基于Streamlit前端聊天页面开发

只用 Python 也能做出很漂亮的网站?Streamlit 说可以。

1741522273918

Streamlit 官方介绍:能在几分钟内把 Python 脚本变成可分享的网站。只需使用纯 Python ,无需前端经验。甚至,你只需要懂 markdown ,然后按照一定规则去做也能搞个网页出来。它还支持免费部署。

官方网站:https://streamlit.io/

image-20240713084559617

Streamlit安装

首先你的电脑需要有 python 环境。

python 环境后,使用下面这条命令就可以安装 streamlit

1
pip install streamlit==1.32.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

安装 streamlit 成功后可以使用下面这条命令看看能不能运行起来。

1
streamlit hello

基础语法

标题

使用 st.title() 可以设置标题内容。

1
st.title('Streamlit教程')

段落write

段落就是 HTML 里的 <p> 元素,在 streamlit 里使用 st.write('内容') 的方式去书写。

1
2
3
import streamlit as st

st.write('Hello')

使用markdown

streamlit 是支持使用 markdown 语法来写页面内容的,只需使用单引号或者双引号的方式将内容包起来,并且使用 markdown 的语法进行书写,页面就会出现对应样式的内容。

1
2
3
4
5
6
7
8
import streamlit as st

"# 1级标题"
"## 2级标题"
"### 3级标题"
"#### 4级标题"
"##### 5级标题"
"###### 6级标题"

图片

渲染图片可以使用 st.image() 方法,也可以使用 markdown 的语法。

st.image(图片地址, [图片宽度]) ,其中图片宽度不是必填项。

1
2
3
import streamlit as st

st.image('./avatar.jpg', width=400)

表格

streamlit 有静态表格和可交互表格。表格在数据分析里属于常用组件,所以 streamlit 的表格也支持 pandasDataFrame

静态表格 table

静态表格使用 st.table() 渲染,出来的效果就是 HTML<table>

st.table() 支持传入字典、pandas.DataFrame 等数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import streamlit as st
import pandas as pd

st.write('dict字典形式的静态表格')
st.table(data={
'name': ['张三', '李四', '王五'],
'age': [18, 20, 22],
'gender': ['男', '女', '男']
})

st.write('pandas中dataframe形式的静态表格')

df = pd.DataFrame(
{
'name': ['张三', '李四', '王五'],
'age': [18, 20, 22],
'gender': ['男', '女', '男']
}
)
st.table(df)

可交互表格 dataframe

可交互表格使用 st.dataframe() 方法创建,和 st.table() 不同,st.dataframe() 创建出来的表格支持按列排序、搜索、导出等功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import streamlit as st
import pandas as pd

st.write('dict字典形式的可交互表格')
st.dataframe(data={
'name': ['张三', '李四', '王五'],
'age': [18, 20, 22],
'gender': ['男', '女', '男']
})

st.write('pandas中dataframe形式的可交互表格')
df = pd.DataFrame(
{
'name': ['张三', '李四', '王五'],
'age': [18, 20, 22],
'gender': ['男', '女', '男']
}
)
st.dataframe(df)

分割线

分隔线就是 HTML 里的 <hr> 。在 streamlit 里使用 st.divider() 方法绘制分隔线。

1
2
3
import streamlit as st

st.divider()

输入框

知道怎么声明变量后,可以使用一个变量接收输入框的内容。

输入框又可以设置不同的类型,比如普通的文本输入框、密码输入框。

  • 普通输入框

输入框使用 st.text_input() 渲染。

1
2
3
4
name = st.text_input('请输入你的名字:')

if name:
st.write(f'你好,{name}')

☆ 密码

如果要使用密码框,可以给 st.text_input() 加多个类型 type="password"

1
2
3
import streamlit as st

pwd = st.text_input('密码是多少?', type='password')

☆ 数字输入框 number_input

数字输入框需要使用 number_input

1
2
3
4
5
import streamlit as st

age = st.number_input('年龄:')

st.write(f'你输入的年龄是{age}岁')

众所周知,正常表达年龄是不带小数位的,所以我们可以设置 st.number_input() 的步长为1,参数名叫 step

1
2
3
# 省略部分代码

st.number_input('年龄:', step=1)

这个步长可以根据你的需求来设置,设置完后,输入框右侧的加减号每点击一次就根据你设置的步长相应的增加或者减少。

还有一点,人年龄不可能是负数,通常也不会大于200。可以通过 min_valuemax_value 设置最小值和最大值。同时还可以通过 value 设置默认值。

1
st.number_input('年龄:', value=20, min_value=0, max_value=200, step=1)

多行文本框 text_area

创建多行文本框使用的是 st.text_area(),用法和 st.text_input() 差不多。

1
2
3
import streamlit as st

paragraph = st.text_area("多行内容:")

Chat Elements

  • Chat文本输入框

    1
    2
    3
    4
    5
    import streamlit as st

    prompt = st.chat_input("Say something")
    if prompt:
    st.write(f"User has sent the following prompt: {prompt}")
  • Chat Message

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 导入 Streamlit 库,Streamlit 是一个用于快速创建数据应用的 Python 库
import streamlit as st

# 使用 st.chat_input 创建一个聊天输入框,提示用户输入问题
prompt = st.chat_input('请输入您的问题: ')

st.write(f'您的问题是: {prompt}')

# 使用 st.chat_message 创建一个用户消息容器,用于显示用户的消息
# 'user' 表示这是用户发送的消息
with st.chat_message('user'):
# 在用户消息容器中显示文本 'Hello '
st.write('Hello ')

# 使用 st.chat_message 创建一个消息容器,用于显示回复消息
message = st.chat_message('assistant')
# 在消息容器中显示文本 'Hello Human',模拟助手的回复
message.write('Hello Human')

小结

  • 实现基于Streamlit前端页面开发
    • 标题:
    • 输入框
    • 多行文本框

【掌握】Ollama平台聊天机器人实现

学习目标

实现基于Python调用Qwen模型API接口聊天机器人开发

需求

构建一个基于大模型的本地智能聊天机器人,利用其强大的自然语言处理和生成能力,为用户提供高效、精准、个性化的对话服务。该聊天机器人将集成先进的大规模预训练语言模型(如GPT、Qwen等),具备自然语言理解、多轮对话、情感分析、知识问答等核心功能,并可根据具体应用场景进行定制化扩展,例如客服咨询、教育辅导、娱乐互动等。

项目采用模块化设计,前端通过Streamlit等框架实现简洁易用的交互界面,后端基于Ollama等平台进行模型部署和管理,确保系统的高效性和可扩展性。项目目标是打造一个智能化、人性化的聊天机器人,提升用户体验,降低人工成本,并探索大模型技术在不同领域的创新应用。

模型调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1. 导入相关包
import ollama

# 2. 定义一个函数,用于发起请求,返回结果
# def get_response(prompt):
# messages = []
# messages.append({'role': 'user', 'content': prompt, })
# response = ollama.chat(model='qwen2.5:7b', messages=messages)
# return response['message']['content']

# 3. 定义一个函数,用于发起请求,返回结果
def get_response(prompt):
# response = ollama.chat(model='qwen2:0.5b', messages=prompt[-50:])
response = ollama.chat(model='deepseek-r1:8b', messages=prompt[-50:])
return response['message']['content']


# 7. 测试,测试结束后,终止
if __name__ == '__main__':
s=input("请输入你要表达的内容")
while True:

prompt = s
result = get_response(prompt)
print(result)

前端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. 导入相关包,如streamlit包
import streamlit as st
from langchain.memory import ConversationBufferMemory
from utils import get_response

# 3. 主界面主标题
st.title("黑马智聊机器人")

# 5. 会话保持:用于存储会话记录
if "memory" not in st.session_state:
st.session_state['memory'] = ConversationBufferMemory()
st.session_state['messages'] = [{'role': 'assistant', 'content': '你好,我是黑马智聊机器人,有什么可以帮助你的么?'}]

# 6. 编写一个循环结构,用于打印会话记录
for message in st.session_state['messages']:
with st.chat_message(message['role']):
st.markdown(message['content'])

# 4. 创建一个聊天窗口
prompt = st.chat_input("请输入您要咨询的问题:")
# 7. 如果文本框有数据,继续向下执行
if prompt:
st.session_state['messages'].append({'role': 'user', 'content': prompt})
st.chat_message("user").markdown(prompt)
# 10. 向utils工具箱发起请求,返回响应
with st.spinner("AI小助手正在思考中..."):
content = get_response(st.session_state['messages'])
st.session_state['messages'].append({'role': 'assistant', 'content': content})
st.chat_message("assistant").markdown(content)

小结

  • 实现基于Python调用Qwen模型API接口聊天机器人开发
    • 实现前端页面开发
    • 完成后端Python业务代码实现

作业

结合自己写的聊天机器人,生成学生管理系统框架

LLM-Index

LLM-Index

昨日回顾

1、output parsers

字符串解析器

列表解析器

json解析器

pydantic解析器

自定义解析器

2、memory

ChatMessageHistory

​ history.add_user_message(xxx)

​ history.add_ai_message(xxx)

​ message_to_dict()

​ messages_from_dict()

ConversationChain(自动管理上下文)

​ ConversationChain(llm=model)

​ conversation.predict(input=’xxx’)

3、Index(RAG核心组件)

文件加载器

​ 创建UnstructuredLoader对象load

​ docs = loader.load

​ html可以用自己的html对象

文档分割器

​ 创建文档分割器的对象(separator,chunk_size,chunk_overlap)

​ 单文档切割

​ 多文档切割(打印信息不同,打印出多个document的key,看不到具体内容)

vectorstores

​ 创建向量数据库Chroma(存入的文档,存入的路径,embedding)

​ 加载

​ 查询(要查询的问题,和匹配的文档k数)

检索器(和similarity search方法很相似 retriever=chromadaDB.as_retriever(search_kwargs={k:2})

​ result=retriever.invoke(query)

​ 可以设置检索时候的算法

agent

基于大模型对用户的问题进行思考,并调用工具完成任务:

​ 调用api(tools,model,AgentType.ZERO_SHOT_REACT_DESCRIPTION,verbose=True)

REACT(reason推理+act(调用工具完成任务))循环往复。

tools=load_tools([wikipedia,’llm-math’],)

每一种类型(大概的理论,怎么调用,怎么改动)

项目为什么要调用哪些api

哪些组件、具体作用、使用方式(api)、知道如何修改

RAG项目实战

智能衣答系统(RAG)

物流行业信息咨询智能问答系统(RAG)

目标:用langchain搭建一个系统

解决问题:模型基于过去的经验数据完成训练,

基于企业自有知识微调

基于基于langchain

流程:

索引(数据预处理:文档读取进来,提取内容成字符串,切割成chunk,embedding chunk)

检索:(用户提问题,转换问题为向量embedding,用embedding做相似度(知识向量库里的)匹配 (用向量库做一个能匹配k个答案的检索器)

生成:匹配到top_K个,添加到prompt,提交给LLM生成答案

加载文件、读取文件、文本分割、文本向量化、问题向量、匹配出的k个,匹配出文本作为上下文和问题一起添加到prompt。

智能衣答系统(RAG)

1、项目需求

以一副属性构建本地知识

2、项目思路

离线部分

​ 文件加载

​ 文本切分

​ 向量化

​ 存向量库

在线部分

​ query向量化

​ 在文本向量中匹配出与问句向量相似的topk个

​ 匹配出的文本作为上下文和问题一起添加到prompt中

​ 提交给llm生成答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
P02_project
data
project1
db.py

from langchain_chroma import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from P04_RAG.P02_project.project1.model import embedding

def create_db(file_path,chunk_size=150,chunk_overlap=30,persist_directory='./chroma_data')
第一步:加载文档
loader = TextLoader('../data/衣服属性.txt',encoding='utf-8')
docs = loader.load()
print(docs)
第二步:切分文档
text_splitter = CharacterTextSplitter(separator="\n",chunk_size=150,chunk_overlap=30)
split_texts = text_splitter.split_document(docs)
第三步:将切好的文档存储到向量数据库中(只执行一次即可,下次运行就从模型中加载即可)

Chroma.from_documents(documents=split_texts,
embedding=embedding,
persist_directory=persist_directory)


def get_retriever(embedding,k=2,persist_directory='./chroma_data'):
从构建好的向量数据库中加载数据
vectordb = Chroma(persist_directory='./chroma_data',embedding_function=embedding)
第四步:生成一个检索器
retriever = vectordb.as_retriever(search_kwargs={'k':k})
return retriever


create_db(file_path,chunk_size=150,chunk_overlap=30,persist_directory='./chroma_data'
retriever=get_retriever(embedding,k=2,persist_directory='./chroma_data')


1
2
3
4
5
6
7
8
9
10
11
12
13
model.py

from langchain_community.chat_models import ChatTongyi
from langchain_community.embeddings import DashScopeEmbeddings
from dotenv import load_dotenv
### 加载环境变量
load_dotenv()

### 加载embedding模型
embedding = DashScopeEmbeddings()

### 加载对话的大模型
llm = ChatTongyi(model='qwen-plus')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
main.py



from langchain_core.prompts import PromptTemplate

from P04_RAG.P02_project.project1.db import get_retriever
from P04_RAG.P02_project.project1.model import embedding, llm

1、获取检索器
retriever = get_retriever(embedding)
def qa(question):
2、将问题送入检索器,获取相似的top-k个文档

docs = retriever.invoke(question)
print(f'docs-->{docs})
related_docs = [doc.page_content for doc in docs]
print(f'related_docs-->{related_docs}')


3、设置提示词模版,包括检索到的文档和用户的问题
template_str = '''
你是一个问答任务助手,使用以下检索到的上下文来回答问题,如果你不知道答案,只需说不知道,回答保持简洁。'''
4、构造提示词
prompt = template.format(question=question,context=related_docs)

5、通过ChatMessageHistory()来存储上下文信息
chat_history = ChatMessageHistory()
chat_history.add_user_message(prompt)

5、调用模型,生成答案
result = llm.invoke(str(chat_history)).content
print(f'result-->{result}')
将大模型的输出保存到chat_history
chat_history.add_ai_message(result)

return result


if __name__ == __main__
question = '我身高170,体重140斤,买多大尺码'
retult = qa(question)

question = '我的体重是多少'
result = qa(question)

1
2
3
4
5
6
7
8
9
10
11
12
13
Conversational
condense question prompt:用于问题“重写”的提示模板
chain type链;stuff:全部塞进去给LLM(简单包里,’map reduce‘:先逐段问,再总结;)

把nexus584问大模型
prompt:nexus584的用户在7月末在csdn上发布了两篇文章,请把他的文章链接给我

chathistory
总结:使用ConversationalRetrieverchain
提示词模版+问题
原始的提示词;大模型的提示词(把对话信息加载进来了)


实现前端问答系统界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import streamlit as st




st.title('智能衣答系统')
st.chat_input()
response = chat_history2[-1][1]

初始化会话状态,如果没有则创建

使用session state方式来储存对话历史,也就是将其设置为全局变量

user input



在页面上显示模型生成的回复

读取pdf,可以用不同的文档加载器的api ;called as PDF

部署本地大模型

  • 了解私有化大模型
  • 掌握Ollama安装与部署
  • 熟悉Ollama客户端命令
  • 掌握基于Ollama平台的ChatBot聊天机器人

【了解】私有大模型

学习目标

了解私有化大模型解决方案,能够选择企业常用的方案实现私有大模型部署

为什么要有私有大模型

随着AI技术的不断普及,人们也积极拥抱其带来的变化,在生活或者工作中亦使用AI技术来帮助我们更高效的完成某些事件,但是在这个过程中,也暴露出AI技术当前下存在在的系列问题,其中最严重的就是安全问题

比如:最典型的是三星员工使用ChatGPT泄露公司机密的案例。

image-20240907150639348

其实上述案例表现的就是企业数据隐私与安全的问题,在许多行业,如金融、医疗、政府等,数据隐私和安全是至关重要的。使用公共大模型可能涉及敏感数据的泄露风险,因为公共模型在训练过程中可能接触到了来自不同来源的敏感数据。因此就有了私有大模型的市场需求,私有大模型允许企业或机构在自己的数据上训练模型,而且训练的结果只供内部或合作伙伴使用,从而确保了数据隐私和安全。

当然除了数据隐私问题原因之外,还存有便于内部员工工作提效、大模型开发的投入等诸多原因综合,直接推动私有大模型成为未来AI发展的新方向之一。

私有大模型解决方案

随着AI的发展,越来越多的开发者投入到大模型开发中,他们期望能自身笔记本上运行大模型,以便开发。越来越多的企业积极改造自身产品,融入AI技术,他们期望能私有化大模型以保证数据安全。这些诉求直接推动社区出现了两个这方面的产品Ollama和LMstudio。

这两个产品各有优势:

Ollama LM Studio
产品定位 开源的大型语言模型本地运行框架 闭源的本地大型语言模型工作站,集模型训练、部署、调试于一体
技术特点 高度智能化,自主学习和适应能力强- 便捷性高,操作简单易懂- 安全性强,数据传输和存储严格保护 高性能,采用先进计算架构和算法优化- 可定制化,支持用户定制模型结构和训练策略易用性,友好的用户界面和丰富的文档支持
功能 提供预训练模型访问和微调功能- 支持多种模型架构和定制模型- 用户友好界面,简化模型实验和部署过程 丰富的训练数据和算法库- 可视化训练监控界面- 强大的调试工具,支持模型性能优化
应用场景 学术研究- 开发者原型设计和实验- 创意写作、文本生成等 智能客服- 自然语言处理(如文本分类、情感分析、机器翻译)- 学术研究
用户友好性 界面化操作,适合不同水平的用户- 支持多种设备和平台 友好的用户界面,适合初学者和非技术人员- 提供全面的工具组合,易于上手
定制性 提供一定程度的定制选项,但可能有限制 高度可定制化,满足用户个性化需求
资源要求 需要一定的内存或显存资源来运行大型模型- 支持跨平台(macOS、Linux,Windows预览版) 构建和训练复杂模型可能需要大量计算资源和专业技能
成本 成本可能根据使用量和资源需求变化- 开源项目,可能涉及较少的直接成本 闭源产品,成本可能包括软件许可和可能的云服务费用
社区生态 社区生态活跃,开发者主流本地运行时- 快速适配新发布的模型 未知(未提及具体社区生态活跃度)

选择私有化大模型部署方案

Ollama 作为一个开源的轻量级工具,适合熟悉命令行界面的开发人员和高级用户进行模型实验和微调。它提供了广泛的预训练模型和灵活的定制选项,同时保持了高度的便捷性和安全性。最重要它是开源的,同时还提供API,对于开发有先天优势,因此在企业中备受欢迎和使用,因此本课程也才主要学习Ollama技术。

小结

  • 了解私有化大模型解决方案
    • Ollama:开源的大型语言模型本地运行框架
    • LM Studio:闭源的本地大型语言模型工作站,集模型训练、部署、调试于一体

【实操】Ollama安装与使用

学习目标

通过安装Ollama工具,实现基于Ollama运行通义QWen大模型

什么是Ollama

Ollama:是一款旨在简化大型语言模型本地部署和运行过程的开源软件。

中文名:羊驼

网址:https://ollama.com/

Ollama提供了一个轻量级、易于扩展的框架,让开发者能够在本地机器上轻松构建和管理LLMs(大型语言模型)。通过Ollama,开发者可以访问和运行一系列预构建的模型,或者导入和定制自己的模型,无需关注复杂的底层实现细节。

Ollama的主要功能包括快速部署和运行各种大语言模型,如Llama 2、Code Llama等。它还支持从GGUF、PyTorch或Safetensors格式导入自定义模型,并提供了丰富的API和CLI命令行工具,方便开发者进行高级定制和应用开发。

image-20240618153540896

Ollama特点

  • 一站式管理
    • Ollama将模型权重、配置和数据捆绑到一个包中,定义成Modelfile,从而优化了设置和配置细节。
    • 包括GPU使用情况。这种封装方式使得用户无需关注底层实现细节,即可快速部署和运行复杂的大语言模型。
  • 热加载模型文件
    • 支持热加载模型文件,无需重新启动即可切换不同的模型,
    • 提高了灵活性,还显著增强了用户体验。
  • 丰富的模型库:提供多种预构建的模型,如Llama 2、Llama 3、通义千问,方便用户快速在本地运行大型语言模型。
  • 多平台支持:支持多种操作系统,包括Mac、Windows和Linux,确保了广泛的可用性和灵活性。
  • 无复杂依赖:优化推理代码减少不必要的依赖,可以在各种硬件上高效运行。包括纯CPU推理和Apple Silicon架构。
  • 资源占用少:Ollama的代码简洁明了,运行时占用资源少,使其能够在本地高效运行,不需要大量的计算资源。

Ollama下载与安装

Ollama下载

Ollama共支持三种平台:

Windows平台安装

  • Windows安装

    1
    2
    3
    4
    5
    第一步:在02_资料/OllamaSetup.exe 找到执行程序

    第二步:右键以管理员身份运行

    第三步:点击install

    1739642839675

  • 验证安装成功

    1
    2
    3
    4
    5
    6
    7
    第一步:win+R组合键  输入cmd

    第二步: 输入命令 ollama -v

    第三步:显示ollama版本号 ollama version is 0.5.4

    即安装成功!

    1739641908819

Linux下载与安装

  • 手动安装

    window和mac版本直接下载安装或解压即可使用。这里由于Ollama需要安装在linux中,因此在这里主要学习如何在Linux上安装:

    Step 1. 安装

    在虚拟机/root/resource目录中已经下载好Linux版本所需的ollama-linux-amd64.tgz文件,则执行下面命令开始安装:

    1
    >tar -C /usr -xzf ollama-linux-amd64.tgz

    操作成功之后,可以通过查看版本指令来验证是否安装成功

    1
    2
    3
    >[root@bogon resource]# ollama -v
    >Warning: could not connect to a running Ollama instance
    >Warning: client version is 0.3.9

    Step 2. 添加开启自启服务

    创建服务文件/etc/systemd/system/ollama.service,并写入文件内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >[Unit]
    >Description=Ollama Service
    >After=network-online.target

    >[Service]
    >ExecStart=/usr/bin/ollama serve
    >User=root
    >Group=root
    >Restart=always
    >RestartSec=3

    >[Install]
    >WantedBy=default.target

    生效服务:

    1
    2
    systemctl daemon-reload
    >systemctl enable ollama

    启动服务:

    1
    >sudo systemctl start ollama
  • 一键安装

    Ollama在Linux上也提供了简便的安装命令,但是过程中需要下载400M左右的数据,比较慢,因此课堂上采用第一种方式安装,但在工作中一般采用下面命令进行安装:

    1
    curl -fsSL https://ollama.com/install.sh | sh

运行通义千问大模型

首次运行

通义千问(Qwen)是阿里巴巴集团Qwen团队研发的大语言模型和大型多模态模型系列。Qwen具备自然语言理解、文本生成、视觉理解、音频理解、工具使用、角色扮演、作为AI Agent进行互动等多种能力。

官网:https://qwen.readthedocs.io/zh-cn

在终端输入一下命令即可运行通义千问大模型: ollama run qwen2:0.5b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@bogon resource]# ollama run qwen2:0.5b
pulling manifest
pulling 8de95da68dc4... 100% ▕█████████████████████████████████████████████████████████████████████████████████▏ 352 MB
pulling 62fbfd9ed093... 100% ▕█████████████████████████████████████████████████████████████████████████████████▏ 182 B
pulling c156170b718e... 100% ▕█████████████████████████████████████████████████████████████████████████████████▏ 11 KB
pulling f02dd72bb242... 100% ▕█████████████████████████████████████████████████████████████████████████████████▏ 59 B
pulling 2184ab82477b... 100% ▕█████████████████████████████████████████████████████████████████████████████████▏ 488 B
verifying sha256 digest
writing manifest
removing any unused layers
success
>>> 您好
你好!有什么可以帮助你的?

>>> 你是什么大模型
我是来自于阿里云的预训练模型,我叫通义千问。我可以回答您关于计算机科学、机器学习等领域的各种问题,也可以进行自然语言处理、聊天机器人、智能问答等任务。我的设计目的是让计算机能够像人类一样思考和解决问题。

命令解释:

第1行:为运行一个本地大模型的命令,这个命令的格式为:

1
ollama run 模型名称:模型规模

第2~11行:如果首次运行,本地没有大模型则会从远程下载大模型

第12~16行:运行成功模型之后,通过终端进行对话聊天

修改模型路径

直接运行上述小节命令,会下载300多M的数据,比较慢,而在虚拟机中已经提前下载好了相关模型(包括后续用到的模型),存储在/root/ollama目录中,因此这里我们需要修改ollama的模型路径,ollama软件在各个操作系统上的默认存储路径是:

macOS: ~/.ollama/models
Linux: ~/.ollama/models
Windows: ~/.ollama/models

要修改其默认存储路径,需要通过设置系统环境变量来实现,即在/etc/profile文件中最后增加一下环境变量:

1
export OLLAMA_MODELS=/root/ollama

然后执行一下命令,生效环境变量:

1
2
3
4
[root@bogon ollama]# source /etc/profile
[root@bogon ollama]# echo $OLLAMA_MODELS
/root/ollama
[root@bogon ollama]#

然后重新ollama服务,则会跳过下载,直接进入大模型,对话完成后可以通过/bye指令终止对话:

1
2
3
4
5
6
7
8
[root@bogon ollama]# systemctl stop ollama
[root@bogon ollama]# ollama serve &
[root@bogon ~]# ollama run qwen2:0.5b
>>> 您好
很高兴为您服务!有什么问题或需要帮助的吗?

>>> /bye
[root@bogon ~]#

让重启也支持模型路径:

上述方式修改后,通过ollama命令是生效的,但是重启电脑则不生效,要解决这个问题,则还需要进行如下配置:

修改服务文件/etc/systemd/system/ollama.service内容为一下::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/bin/ollama serve
User=root
Group=root
Restart=always
RestartSec=3
Environment="OLLAMA_MODELS=/root/ollama"

[Install]
WantedBy=default.target

生效修改的配置:

1
2
systemctl daemon-reload
systemctl restart ollama

对话指令初体验

在Ollama终端中提供了一系列指令,可以用来调整和控制对话模型:

image-20240618153540896

/? 该指令主要是列出支持的指令列表

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@bogon ~]#  ollama run qwen2:0.5b
>>> /?
Available Commands:
/set Set session variables
/show Show model information
/load <model> Load a session or model
/save <model> Save your current session
/clear Clear session context
/bye Exit
/?, /help Help for a command
/? shortcuts Help for keyboard shortcuts

Use """ to begin a multi-line message.

小结

  • 通过安装Ollama工具,实现基于Ollama运行通义QWen大模型
    • 完成Ollama软件安装
    • 实现Qwen模型本地部署

【熟悉】对话指令详解

学习目标

掌握基于Ollama客户端相关命令,完成对大模型进行操作

/bye 指令

退出当前控制台对话, 快捷键: ctrl + d

1
2
3
4
5
6
[root@bogon ~]#  ollama run qwen2:0.5b
>>> 您好
你好!有什么可以帮助您的吗?

>>> /bye
[root@bogon ~]#

/show指令

/show 指令:用于查看当前模型详细信息

1
2
3
4
5
6
7
8
9
[root@bogon ~]#  ollama run qwen2:0.5b
>>> /show
Available Commands:
/show info 查看模型的基本信息
/show license 查看模型的许可信息
/show modelfile 查看模型的制作源文件Modelfile
/show parameters 查看模型的内置参数信息
/show system 查看模型的内置Sytem信息
/show template 查看模型的提示词模版

/show info 查看模型的基本信息

1
2
3
4
5
>>> /show info
Model details:
Family qwen2 模型名称
Parameter Size 494.03M 模型大小
Quantization Level Q4_0 模型量化级别

/show license 查看模型的许可信息—开源软件的许可协议

1
2
3
4
5
6
7
8
>>> /show license

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
............................................................

/show modelfile 查看模型的制作源文件Modelfile

modelfile :文件是用来制作私有模型的脚步文件,后续课程学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> /show modelfile
# Modelfile generated by "ollama show"
# To build a new Modelfile based on this, replace FROM with:
# FROM qwen2:0.5b

FROM /root/ollama/blobs/sha256-8de95da68dc485c0889c205384c24642f83ca18d089559c977ffc6a3972a71a8
TEMPLATE "{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}<|im_end|>
"
PARAMETER stop <|im_start|>
PARAMETER stop <|im_end|>
LICENSE """
......................................................................

/show parameters 查看模型的内置参数信息

1
2
3
4
>>> /show parameters
Model defined parameters:
stop "<|im_start|>"
stop "<|im_end|>"

/show system 查看模型的内置system信息—system常常用来定一些对话角色扮演

1
2
>>> /show system
No system message was specified for this model.

/show template 查看模型的提示词模版

template:是最终传入大模型的字符串模版,模版中的内容由上层应用动态传入

1
2
3
4
5
6
7
>>> /show template
{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}<|im_end|>

/? shortcuts 指令

查看在控制台中可用的快捷键

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> /? shortcuts
Available keyboard shortcuts:
Ctrl + a 移动到行头
Ctrl + e 移动到行尾
Ctrl + b 移动到单词左边
Ctrl + f 移动到单词右边
Ctrl + k 删除游标后面的内容
Ctrl + u 删除游标前面的内容
Ctrl + w 删除游标前面的单词

Ctrl + l 清屏
Ctrl + c 停止推理输出
Ctrl + d 退出对话(只有在没有输入时才生效)

“”” 指令

“”” 用于输入内容有换行时使用,如何多行输入结束也使用 “””

1
2
3
4
5
>>> """
... 您好
... 你是什么模型?
... """
我是一个计算机程序,可以回答您的问题、提供信息和执行任务。请问您有什么问题或者指令想要我帮助您?

/set 指令

set指令主要用来设置当前对话模型的系列参数

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> /set
Available Commands:
/set parameter ... 设置对话参数
/set system <string> 设置系统角色
/set template <string> 设置推理模版
/set history 开启对话历史
/set nohistory 关闭对话历史
/set wordwrap 开启自动换行
/set nowordwrap 关闭自动换行
/set format json 输出JSON格式
/set noformat 关闭格式输出
/set verbose 开启对话统计日志
/set quiet 关闭对话统计日志

/set parameter … 设置对话参数

1
2
3
4
5
6
7
8
9
10
11
12
>>> /set parameter
Available Parameters:
/set parameter seed <int> Random number seed
/set parameter num_predict <int> Max number of tokens to predict
/set parameter top_k <int> Pick from top k num of tokens
/set parameter top_p <float> Pick token based on sum of probabilities
/set parameter num_ctx <int> Set the context size
/set parameter temperature <float> Set creativity level
/set parameter repeat_penalty <float> How strongly to penalize repetitions
/set parameter repeat_last_n <int> Set how far back to look for repetitions
/set parameter num_gpu <int> The number of layers to send to the GPU
/set parameter stop <string> <string> ... Set the stop parameters
Parameter Description Value Type Example Usage
num_ctx 设置上下文token大小. (默认: 2048) int num_ctx 4096
repeat_last_n 设置模型要回顾的距离以防止重复. (默认: 64, 0 = 禁用, -1 = num_ctx) int repeat_last_n 64
repeat_penalty 设置惩罚重复的强度。较高的值(例如,1.5)将更强烈地惩罚重复,而较低值(例如,0.9)会更加宽容。(默认值:1.1) float repeat_penalty 1.1
temperature 模型的温度。提高温度将使模型的答案更有创造性。(默认值:0.8) float temperature 0.7
seed 设置用于生成的随机数种子。将其设置为特定的数字将使模型为相同的提示生成相同的文本。(默认值:0) int seed 42
stop 设置停止词。当遇到这种词时,LLM将停止生成文本并返回 string stop “AI assistant:”
num_predict 生成文本时要预测的最大标记数。(默认值:128,-1 =无限生成,-2 =填充上下文) int num_predict 42
top_k 减少产生无意义的可能性。较高的值(例如100)将给出更多样化的答案,而较低的值(例如10)将更加保守。(默认值:40) int top_k 40
top_p 与Top-K合作。较高的值(例如,0.95)将导致更多样化的文本,而较低的值(例如,0.5)将产生更集中和保守的文本。(默认值:0.9) float top_p 0.9
num_gpu 设置缓存到GPU显存中的模型层数 int 自动计算

JSON格式输出

1
2
3
4
5
6
7
8
9
>>> /set format json
Set format to 'json' mode.
>>> 您好
{"response":"你好,欢迎光临,请问有什么我可以帮助您的吗?"}

>>> /set noformat
Disabled format.
>>> 您好
Hello! How can I assist you?

输出对话统计日志

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> /set verbose
Set 'verbose' mode.
>>> 您好
您好!我需要您的信息,以便回答您的问题。请问您能告诉我更多关于这个主题的信息吗?

total duration: 1.642906162s 总耗时
load duration: 3.401367ms 加载模型数据耗时
prompt eval count: 11 token(s) 提示词token消耗数量
prompt eval duration: 196.52ms 提示词处理耗时
prompt eval rate: 55.97 tokens/s 提示词处理速率
eval count: 24 token(s) 响应token消耗数量
eval duration: 1.304188s 响应处理耗时
eval rate: 18.40 tokens/s 响应处理速率

/clear 指令

在命令行终端中对话是自带上下文记忆功能,如果要清除上下文功能,则使用/clear指令清除上下文内容,例如:

前2个问题都关联的,在输入/clear则把前2个问题的内容给清理掉了,第3次提问时则找不到开始的上下文了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> 请帮我出1道java list的单选题 
以下是一些关于Java List的单选题:

1. 在Java中,List是哪一种数据结构?
2. Java中的顺序存储方式(例如:使用数组)主要用来做什么?
3. 一个列表对象可以包含哪些类型的元素?

>>> 再出1道
以下是一些关于Java List的单选题:

4. 在Java中,List接口用于创建和操作集合。
5. Java中的顺序存储方式(如:使用数组)的主要优势有哪些?
6. 一个列表对象可以包含哪些类型?

>>> /clear
Cleared session context
>>> 在出1道
很抱歉,我无法理解您的问题。您能否提供更多的背景信息或者问题描述,以便我能更好地帮助您?

/load 指令

load可以在对话过程中随时切换大模型

1
2
3
4
5
6
7
8
9
>>> 你是什么大模型
我是一个基于开放AI平台的模型,拥有一个强大的数学推理能力,并且在各种自然语言处理任务上都表现优秀。我可以回答您提出的问题,也可以提供与主题相关的信息和建议。如果您有任何问题或需要帮助,
请随时告诉我!

>>> /load deepseek-coder
Loading model 'deepseek-coder'
>>> 你是什么大模型
我是由中国的深度求索(DeepSeek)公司开发的编程智能助手,名为 Deepseek Coder。我主要用于解答和协助计算机科学相关的问题、问题解决方案等任务。我的设计目标是提供最全面准确的高质量服务来帮
助用户理解复杂的新技术或概念并迅速找到它们在实际应用中的实现方法或者原理所在的地方。

/save 指令

可以把当前对话模型存储成一个新的模型

1
2
>>> /save test
Created new model 'test'

保存的模型存储在ollama的model文件中,进入下面路径即可看见模型文件test:

1
2
3
4
[root@bogon library]# pwd
/root/ollama/manifests/registry.ollama.ai/library
[root@bogon library]# ls
deepseek-coder qwen2 test

小结

  • 掌握基于Ollama客户端相关命令
    • /bye指令 :退出当前控制台对话
    • /show指令:用于查看当前模型详细信息
    • /load指令:可以在对话过程中随时切换大模型
    • /set指令:指令主要用来设置当前对话模型的系列参数
    • clear指令:清除上下文内容

【熟练】客户端命令详解

Ollama客户端还提供了系列命令,来管理本地大模型,接下来就先了解一下相关命令:

g6

run 命令

run命令主要用于运行一个大模型,命令格式是:

1
2
3
ollama run MODEL[:Version] [PROMPT] [flags]
比如,运行通义千问命令:
ollama run qwen2:0.5b

[:Version] 可以理解成版本,而版本信息常常以大模型规模来命名,可以不写,不写则模式成latest

1
2
3
ollama run qwen2
等同
ollama run qwen2:latest

[PROMPT] 参数是用户输入的提示词,如果带有此参数则,run命令会执行了输入提示词之后即退出终端,即只对话一次。

1
2
3
4
[root@bogon ~]#  ollama run qwen2:0.5b 您好
您好!有什么问题我可以帮助您?

[root@bogon ~]#

[flags] 指定运行时的参数

1
2
3
4
5
6
Flags:
--format string 指定运行的模型输出格式 (比如. json)
--insecure 使用非安全模,比如在下载模型时会忽略https的安全证书
--keepalive string 指定模型在内存中的存活时间
--nowordwrap 关闭单词自动换行功能
--verbose 开启统计日志信息

例如,在启动时增加 –verbose参数,则在对话时,自动增加统计token信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@bogon ~]# ollama run qwen2:0.5b --verbose
>>> 您好
欢迎光临,我可以为您提供帮助。有什么问题或需要帮助的地方?

total duration: 1.229917477s
load duration: 3.027073ms
prompt eval count: 10 token(s)
prompt eval duration: 167.181ms
prompt eval rate: 59.82 tokens/s
eval count: 16 token(s)
eval duration: 928.995ms
eval rate: 17.22 tokens/s

show 命令

不用运行大模型,查看模型的信息,与之前所学的/show功能类似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@bogon ~]# ollama show -h
Show information for a model

Usage:
ollama show MODEL [flags]

Flags:
-h, --help 查看使用帮助
--license 查看模型的许可信息
--modelfile 查看模型的制作源文件Modelfile
--parameters 查看模型的内置参数信息
--system 查看模型的内置Sytem信息
--template 查看模型的提示词模版

例如,查看提示词模版:

1
2
3
4
5
6
7
[root@bogon ~]# ollama show qwen2 --template
{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}<|im_end|>

pull 命令

查询模型名称的网站:https://ollama.com/

从远程下载一个模型,命令格式是:

1
ollama pull MODEL[:Version] [flags]

[:Version] 可以理解成版本,但在这里理解成大模型规模,可以不写,不写则模式成latest

1
2
3
ollama pull qwen2
等同
ollama pull qwen2:latest

[flags] 参数,目前只有一个–insecure参数,用于来指定非安全模式下载数据

1
ollama pull qwen2 --insecure

list/ls 命令

查看本地下载的大模型列表,也可以使用简写ls

1
2
3
4
5
6
7
8
9
10
[root@bogon ~]# ollama list
NAME ID SIZE MODIFIED
qwen2:latest e0d4e1163c58 4.4 GB 10 minutes ago
deepseek-coder:latest 3ddd2d3fc8d2 776 MB 3 hours ago
qwen2:0.5b 6f48b936a09f 352 MB 8 hours ago
[root@bogon ~]# ollama ls
NAME ID SIZE MODIFIED
qwen2:latest e0d4e1163c58 4.4 GB 10 minutes ago
deepseek-coder:latest 3ddd2d3fc8d2 776 MB 3 hours ago
qwen2:0.5b 6f48b936a09f 352 MB 8 hours ago

列表字段说明:

  • NAME:名称
  • ID:大模型唯一ID
  • SIZE:大模型大小
  • MODIFIED:本地存活时间

注意:在ollama的其它命令中,不能像docker一下使用ID或ID缩写,这里只能使用大模型全名称。

ps 命令

查看当前运行的大模型列表,PS命令没其它参数

1
2
3
[root@bogon ~]# ollama ps
NAME ID SIZE PROCESSOR UNTIL
deepseek-coder:latest 3ddd2d3fc8d2 1.3 GB 100% CPU About a minute from now

列表字段说明:

  • NAME:大模型名称
  • ID:唯一ID
  • SIZE:模型大小
  • PROCESSOR:资源占用
  • UNTIL:运行存活时长

rm 命令

删除本地大模型,RM命令没其它参数

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost system]# ollama ls
NAME ID SIZE MODIFIED
qwen2:latest e0d4e1163c58 4.4 GB 16 hours ago
deepseek-coder:latest 3ddd2d3fc8d2 776 MB 19 hours ago
qwen2:0.5b 6f48b936a09f 352 MB 24 hours ago
[root@localhost system]# ollama rm qwen2:0.5b
deleted 'qwen2:0.5b'
[root@localhost system]# ollama ls
NAME ID SIZE MODIFIED
qwen2:latest e0d4e1163c58 4.4 GB 16 hours ago
deepseek-coder:latest 3ddd2d3fc8d2 776 MB 19 hours ago
[root@localhost system]#

【掌握】OllamaAPI 详解

学习目标

掌握基于Ollama API接口,实现基于API的方式访问

HTTP基础知识

什么是HTTP

HTTP,全称为超文本传输协议(HyperText Transfer Protocol),是互联网上应用最为广泛的一种网络协议。它是客户端和服务器之间进行通信的规则集合,允许将超文本标记语言(HTML)文档从Web服务器传输到Web浏览器。简而言之,HTTP是Web浏览器和Web服务器之间的“语言”,使得用户能够浏览网页、下载文件、提交表单等。

HTTP请求特征

HTTP请求是客户端(如浏览器)向服务器发送的请求消息,用于获取或操作资源。以下是HTTP请求的主要特征:

请求方法
请求方法定义了客户端希望执行的操作类型,常见方法包括:

  • GET:请求获取指定资源。
  • POST:向服务器提交数据,通常用于表单提交。

请求URL
请求URL指定了资源的路径,通常包括协议(如HTTP或HTTPS)、服务器地址、端口号和资源路径。

请求头(Headers)
请求头包含关于请求的附加信息,常见字段包括:

  • Host:指定服务器的主机名和端口号。
  • User-Agent:描述客户端的信息(如浏览器类型)。
  • Accept:指定客户端能够接收的媒体类型。
  • Content-Type:指示请求体的媒体类型(如application/json)。
  • Authorization:包含认证信息(如Bearer Token)

请求体(Request Body)

请求体用于携带客户端发送的数据,通常在POST、PUT等方法中使用。例如:

  • 表单数据:username=test&password=123456
  • JSON数据:{"username": "test", "password": "123456"}

HTTP请求体方法对比

​ 在HTTP协议中,GETPOST是两种最常用的请求方法,它们在用途、数据传递方式、安全性等方面有显著区别。

  • GET
    • 用于请求资源,通常用于从服务器获取数据(如加载网页、查询数据)。
    • 适合幂等操作(多次请求不会对资源产生影响)。
  • POST
    • 用于提交数据,通常用于向服务器发送数据(如表单提交、文件上传)。
    • 适合非幂等操作(多次请求可能会对资源产生影响)。

HTTP状态码分类

​ 200 OK:请求成功,响应中包含请求的数据。

​ 302 Found:资源临时移动到新URL。

​ 404 Not Found:请求的资源不存在。

​ 500 Internal Server Error:服务器内部错误,无法完成请求。

​ 502 Bad Gateway:服务器作为网关时收到无效响应。

API 详解

Ollama对客户端相关的命令也提供API操作的接口,方便在企业应用中通过程序类操作私有大模型。

开通远程访问

为了在本机(开发环境)中能访问虚拟机中的Ollama API,我们需要先开通Ollama的远程访问权限:

Step 1:增加环境变量

在/etc/profile中增加一下环境变量:

1
2
export OLLAMA_HOST=0.0.0.0:11434
export OLLAMA_ORIGINS=*

然后通过一下命令,生效环境变量:

1
source /etc/profile

Step 2:增加服务变量

修改服务文件/etc/systemd/system/ollama.service内容为一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/bin/ollama serve
User=root
Group=root
Restart=always
RestartSec=3
Environment="OLLAMA_MODELS=/root/ollama"
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=*"

[Install]
WantedBy=default.target

生效修改的配置:

1
2
systemctl daemon-reload
systemctl restart ollama

Step 3:开通防火墙

1
2
firewall-cmd --zone=public --add-port=11434/tcp --permanent
firewall-cmd --reload

也可以关闭防火墙:

1
systemctl stop firewalld

导入Apifox文档

为了方便后续使用程序接入Ollama中的大模型,在此可以先通过Apifox进行Api的快速体验与学习。在资料文件夹中《Ollama.apifox.json》文件提供了供Apifox软件导入的json内容,再此我们先导入到Apifox软件中,快速体验一下API相关功能。

Step 1:打开导入项目

bg-7

Step 2:选择导入的文件

bg-9

Step 3:输入项目名称

bg-10

Step 4:完成导入,进入项目

中间如果有导入预览,则直接点击确定即可。

image-20240620203700320

配置环境地址

Oallma支持的API可以在资料文件夹中通过《Ollama API文档.html》了解详解,双击打开查看:

image-20240620174314154

通过网页可以了解到Ollama支持7个API (这里只列举了常用的),接下来我们重点先了解对话和向量化接口,因为这两个接口是最重要的,其它接口则留给大家课后自行尝试,但是在正式体验之前,需要先配置一下环境地址。

配置测试环境地址:

bg41

聊天对话接口说明

聊天对话接口,是实现类似ChatGPT、文心、通义千问等网页对话功能的关键接口,请求的地址与参数如下:

POST /api/chat

{
“model”: “qwen2:0.5b”,
“messages”: [
​ {
​ “role”: “user”,
​ “content”: “你好”
​ }
],

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"model": "qwen2.5:0.5b",
"messages": [
{
"role": "string",
"content": "string",
"images": "string"
}
],
"format": "string",
"stream": true,
"keep_alive": "string",
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The location to get the weather for, e.g. San Francisco, CA"
},
"format": {
"type": "string",
"description": "The format to return the weather in, e.g. 'celsius' or 'fahrenheit'",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location", "format"]
}
}
}
],
"options": {
"seed": 0,
"top_k": 0,
"top_p": 0,
"repeat_last_n": 0,
"temperature": 0,
"repeat_penalty": 0,
"stop": [
"string"
]
}
}

  • 请求参数
名称 位置 类型 必选 中文名 说明
body body object none
model body string 模型名称 none
messages body [object] 聊天消息 none
role body string 角色 system、user或assistant
content body string 内容 none
images body string 图像 none
format body string 响应格式 none
stream body boolean 是否流式生成 none
keep_alive body string 模型内存保持时间 5m
tools body [object] 工具
options body object 配置参数 none
seed body integer 生成种子 none
top_k body integer 多样度 越高越多样,默认40
top_p body number 保守度 越低越保守,默认0.9
repeat_last_n body integer 防重复回顾距离 默认: 64, 0 = 禁用, -1 = num_ctx
temperature body number 温度值 越高创造性越强,默认0.8
repeat_penalty body number 重复惩罚强度 越高惩罚越强,默认1.1
stop body [string] 停止词 none

返回示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"model": "llama3.1",
"created_at": "2024-09-07T09:00:57.035084368Z",
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"function": {
"name": "get_current_weather",
"arguments": {
"format": "celsius",
"location": "Paris"
}
}
}
]
},
"done_reason": "stop",
"done": true,
"total_duration": 14452649821,
"load_duration": 21370256,
"prompt_eval_count": 213,
"prompt_eval_duration": 11306354000,
"eval_count": 25,
"eval_duration": 3082983000
}

  • 返回结果
状态码 状态码含义 说明 数据模型
200 OK 成功 Inline
  • 返回数据结构

状态码 200 时才返回以下信息。

名称 类型 必选 约束 中文名 说明
model string true none 模型 none
created_at string true none 响应时间 none
message object true none 响应内容 none
role string true none 角色 none
content string true none 内容 none
tool_calls [object] false none 调用的工具集
done boolean false none none
total_duration integer false none 总耗时 none
load_duration integer false none 模型加载耗时 none
prompt_eval_count integer false none 提示词token消耗数 none
prompt_eval_duration integer false none 提示词耗时 none
eval_count integer false none 响应token消耗数 none
eval_duration integer false none 响应耗时 none
  • 对话操作演示

image-20240620212328483

视觉对话演示

随着技术与算力的进步,大模型也逐渐分化成多种类型,而在这些种类中比较常见的有:

  • 大语言模型:用于文生文,典型的使用场景是:对话聊天—仅文字对话

    Qwen、ChatGLM3、Baichuan、Mistral、LLaMA3、YI、InternLM2、DeepSeek、Gemma、Grok 等等

  • 文本嵌入模型:用于内容的向量化,典型的使用场景是:模型微调

    text2vec、openai-text embedding、m3e、bge、nomic-embed-text、snowflake-arctic-embed

  • 重排模型:用于向量化数据的优化增强,典型的使用场景是:模型微调

    bce-reranker-base_v1、bge-reranker-large、bge-reranker-v2-gemma、bge-reranker-v2-m3

  • 多模态模型:用于上传文本或图片等信息,然后生成文本或图片,典型的使用场景是:对话聊天—拍照批改作业

    Qwen-VL 、Qwen-Audio、YI-VL、DeepSeek-VL、Llava、MiniCPM-V、InternVL

  • 语音识别语音播报:用于文生音频、音频转文字等,典型的使用场景是:语音合成

    Whisper 、VoiceCraft、StyleTTS 2 、Parler-TTS、XTTS、Genny

  • 扩散模型:用于文生图、文生视频,典型的使用场景是:文生图

    AnimateDiff、StabilityAI系列扩散模型

在这些模型中,Ollama目前仅支持大语言模型、文本嵌入模型、多模态模型,文本嵌入模型在后面的会学习,再此可以先来体验一下多模态模型:

Step 1:私有化多模态大模型

LLaVA( Large Language and Vision Assistant)是一个开源的多模态大模型,它可以同时处理文本、图像和其他类型的数据,实现跨模态的理解和生成。

网址:https://github.com/haotian-liu/LLaVA.git

1
ollama run llava --keepalive 1h

Step 2:准备图片素材

准备一张图片:

Snipaste_2024-06-22_16-01-31

然后通过程序把图片数据转出Base64字符串:

1
2
3
4
5
6
7
8
9
10
11
import base64
def main():
# 读取文件内容
with open("..Snipaste_2024-06-22_16-01-31.png", "rb") as file:
bytes_data = file.read()
# 将字节数据编码为Base64字符串
base64_str = base64.b64encode(bytes_data).decode('utf-8')
# 打印Base64字符串
print(base64_str)
if __name__ == "__main__":
main()

生成的Base64也可以在【资料/多模态测试图片Base64字符串.txt 】中找到。

Step 3:调用多模态接口

在Ollama中可以通过内容生成接口和聊天对话接口来支持多模态,在此以聊天对话接口为例:

  • 图片信息通过images字段传入,且可传入多张
  • 识别的结果为引文,需要自行翻译

image-20240622163209620

小结

  • 掌握基于Ollama API接口
    • 了解大模型网络调用流程

【实操】ChatBox与Ollama快速搭建ChatBot

学习目标

掌握ChatBox环境搭建,完成ChatBox集成Ollama实现对话

ChatBox是什么

在当前市场上有很多类似ChatGPT、通义、文心、星火等这样的对话大模型供我们使用,帮助我们快速高效的完成日常的工作,但是对于一些企业来说,会存在一些数据安全的问题,因为您输入到大模型中的内容,会进过内部训练,成为大模型的一部分数据。就比如《三星被曝因ChatGPT泄露芯片机密!韩媒:数据「原封不动」传美国》,三星员工把一些内部资料输入到了ChatGPT,则ChatGPT拿到这些资料后,经过训练成模型数据,这样全球用户就都可以访问到这个数据。

企业为避免类似的情况发生,可以采取部署企业私有大模型的方案来解决此问题,这就引出了接下要学习的知识:搭建企业私有ChatBot。要完成这个知识需要先学习一个ChatBox的软件,我们接下来看一下:

Chatbox 是一款基于人工智能技术的对话工具,通常用于提供智能客服、聊天机器人或其他自动化对话服务。它可以帮助企业或个人实现高效的客户沟通、问题解答、任务处理等功能。

1739203773266

ChatBox功能特点包含:

  • 一键免费拥有你自己的 ChatGPT/Gemini/Claude/Ollama 应用
  • 与文档和图片聊天
  • 代码神器:生成与预览
  • 支持本地大模型
  • 支持多平台AI接入
  • 支持插件扩展

安装ChatBox

ChatBox提供了windows桌面安装方式,相关文件已下载到02_资料/Chatbox-1.9.8-Setup.exe,可以找到文件,然后通过以下操作进行安装:

**Step 1:桌面win安装 **

1739643125906

Step 2:访问ChatBox

1739389459468

ChatBox界面介绍

主界面

主界面如下,主要包括的内容有:

  • 功能菜单(左侧)
    • 对话菜单
    • 功能菜单
  • 模型选择

1739207562004

对话聊天界面

从主界面中点击【立即开始】则可快速进入聊天界面,然后与大模型进行聊天

  • 聊天区域:用户可以发送文本、图片等信息,与大模型进行对话
  • 聊天历史:显示历史用户与大模型对话列表
  • 聊天设置:可以进行对话模型切换与参数设置

1739388676991

ChatBox集成Ollama

ChatBox对话聊天实际是调用的第三方AI平台,并且支持非常丰富的平台:

  • AWS Bedrock:集成了 AWS Bedrock 服务,支持了 Claude / LLama2 等模型,提供了强大的自然语言处理能力。
  • Google AI (Gemini Pro、Gemini Vision):接入了 Google 的 Gemini 系列模型,包括 Gemini 和 Gemini Pro,以支持更高级的语言理解和生成。
  • Anthropic (Claude):接入了 Anthropic 的 Claude 系列模型,包括 Claude 3 和 Claude 2,多模态突破,超长上下文,树立行业新基准。
  • ChatGLM:加入了智谱的 ChatGLM 系列模型(GLM-4/GLM-4-vision/GLM-3-turbo),为用户提供了另一种高效的会话模型选择。
  • Moonshot AI (月之暗面):集成了 Moonshot 系列模型,这是一家来自中国的创新性 AI 创业公司,旨在提供更深层次的会话理解。
  • Together.ai:集成部署了数百种开源模型和向量模型,无需本地部署即可随时访问这些模型。
  • 01.AI (零一万物):集成了零一万物模型,系列 API 具备较快的推理速度,这不仅缩短了处理时间,同时也保持了出色的模型效果。
  • Groq:接入了 Groq 的 AI 模型,高效处理消息序列,生成回应,胜任多轮对话及单次交互任务。
  • OpenRouter:其支持包括 Claude 3GemmaMistralLlama2Cohere等模型路由,支持智能路由优化,提升使用效率,开放且灵活。
  • Minimax: 接入了 Minimax 的 AI 模型,包括 MoE 模型 abab6,提供了更多的选择空间。
  • DeepSeek: 接入了 DeepSeek 的 AI 模型,包括最新的 DeepSeek-V2,提供兼顾性能与价格的模型。
  • Qwen: 接入了 Qwen 的 AI 模型,包括最新的 qwen-turboqwen-plusqwen-max 等模型。

除此之外,ChatBox也支持与本地私有部署的大模型就行对话,而这种组合使用场景非常适合数据敏感的企业。

Ollama 支持本地大语言模型

要在ChatBox中使用Ollama中的大模型,也非常便捷,可以按照以下步骤进行操作:

Step 1:运行本地大模型

1
ollama run qwen2 --keepalive 1h

命令说明:

  • 命令运行的是通义大模型
  • 通过--keepalive参数设置大模型被加载到内存中的存活时长为1小时

Step 2:配置Ollama信息

进入对话聊天界面,并点击位置的设置按钮,则弹出下图中间区域的对话框,然后点击位置的【模型】菜单,然后按图填写信息:

1739206990140

Step 3:开始对话

配置完成之后,返回对话界面,在1号位置选择通义大模型,然后即可开始对话聊天。

1739206253326

小结

  • 掌握ChatBox环境搭建
    • 完成ChatBox软件安装
    • 实现ChatBox部署Qwen大模型

【扩展】Windows版本的Ollama安装与DeepSeek大模型部署

cmd进入黑窗口平台

1
键盘组合键 win+r 输入cmd

下载deepseek模型

1
ollama pull deepseek-r1:1.5b

体验deepseek模型

1
ollama run deepseek-r1:1.5b

1739643461782

循环神经网络RNN

1 RNN介绍

1.1 RNN概念

循环神经网络(Recurrent Neural Network, RNN)是一种==专门处理序列数据的神经网络==。与传统的前馈神经网络不同,RNN具有“循环”结构,能够处理和记住前面时间步的信息,使其特别适用于时间序列数据或有时序依赖的任务。

我们要明确什么是序列数据,时间序列数据是指在不同时间点上收集到的数据,这类数据反映了某一事物、现象等随时间的变化状态或程度。这是时间序列数据的定义,当然这里也可以不是时间,比如文字序列,但总归序列数据有一个特点——后面的数据跟前面的数据有关系

1755689321526

1.2 RNN应用场景

  • 自然语言处理(NLP):文本生成、语言建模、机器翻译、情感分析等。
  • 时间序列预测:股市预测、气象预测、传感器数据分析等。
  • 语音识别:将语音信号转换为文字。
  • 音乐生成:通过学习音乐的时序模式来生成新乐曲。

1.3 自然语言处理概述

自然语言处理(Nature language Processing, NLP)研究的主要是==通过计算机算法来理解自然语言。==

对于自然语言来说,处理的数据主要就是人类的语言,例如:汉语、英语、法语等,该类型的数据不像我们前面接触过的结构化数据、或者图像数据可以很方便的进行数值化。

NLP的目标是让机器能够“听懂”和“读懂”自然语言,并进行有效的交流和分析。

NLP涵盖了从文本到语音、从语音到文本的各个方面,它涉及多种技术,包括语法分析、语义理解、情感分析、机器翻译等。

1755689335945

2 词嵌入层

RNN(Recurrent Neural Network) 中,词嵌入层(Word Embedding Layer) 是处理自然语言数据的关键组成部分。它将输入的离散单词(通常是词汇表中的索引)转换为连续的、低维的向量表示,从而使得神经网络能够理解和处理这些词汇的语义信息。

2.1 词嵌入层作用

词嵌入层的主要目的是将每个词映射为一个固定长度的向量(将文本转换为向量),这些向量能够捕捉词与词之间的语义关系。

传统的文本表示方法(如one-hot编码)无法反映单词之间的相似性,因为在one-hot编码中,每个单词都被表示为一个高维稀疏向量,而词嵌入通过低维稠密向量表示单词,能够更好地捕捉词汇之间的语义相似性。

词嵌入层首先会根据输入的词的数量构建一个词向量矩阵,例如: 我们有 100 个词,每个词希望转换成 128 维度的向量,那么构建的矩阵形状即为: 100*128,输入的每个词都对应了一个该矩阵中的一个向量。

1755689346271

词嵌入层在RNN中的作用

  • 输入表示:RNN通常用于处理序列数据。在处理文本时,RNN的输入是由单词构成的序列。由于神经网络不能直接处理离散的单词标识符(如整数索引或字符),因此需要通过词嵌入层将每个单词转换为一个固定长度的稠密向量。这些向量作为RNN的输入,帮助RNN理解词语的语义。
  • 降低维度:词嵌入层将原本高维的稀疏表示(如one-hot编码)转化为低维的稠密向量,减少了计算量,同时保持了词汇之间的语义关系。
  • 捕捉语义相似性:通过训练,词嵌入能够学习到词语之间的关系。例如,语义相似的词(如“猫”和“狗”)在向量空间中会比较接近,而语义不相关的词(如“猫”和“汽车”)则会较为遥远。

2.2 词嵌入层工作流程

  • 初始化词向量:词嵌入层的初始词向量通常会使用随机初始化或者通过加载预训练的词向量(如Word2Vec或GloVe)进行初始化。

  • 输入索引:每个单词在词汇表中都有一个唯一的索引。输入文本(例如一个句子)会先被分词,然后每个单词会被转换为相应的索引。

  • 查找词向量:词嵌入层将这些单词索引映射为对应的词向量。这些词向量是一个低维稠密向量,表示该词的语义。

  • 输入到RNN:这些词向量作为RNN的输入,RNN处理它们并根据上下文生成一个序列的输出。

2.3 词嵌入层使用

在PyTorch中,我们可以使用 nn.Embedding 词嵌入层来实现输入词的向量化

nn.Embedding 对象构建时,最主要有两个参数:

  • num_embeddings:表示词的数量

  • embedding_dim:表示用多少维的向量来表示每个词

1
nn.Embedding(num_embeddings=10, embedding_dim=4)

接下来,我们将会学习如何将词转换为词向量,其步骤如下:

  1. 先将语料进行分词,构建词与索引的映射,我们可以把这个映射叫做词表,词表中每个词都对应了一个唯一的索引;
  2. 然后使用 nn.Embedding 构建词嵌入矩阵,词索引对应的向量即为该词对应的数值化后的向量表示。

例如,我们的文本数据为: “北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途。”,接下来,我们看下如何使用词嵌入层将其进行转换为向量表示,步骤如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import torch
import torch.nn as nn
import jieba # pip install jieba -i https://pypi.mirrors.ustc.edu.cn/simple/


if __name__ == '__main__':
# 0.文本数据
text = '北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途。'
# 1. 文本分词
words = jieba.lcut(text)
print('文本分词:', words)
# 2.分词去重并保留原来的顺序获取所有的词语
unique_words = list(set(words))
print("去重后词的个数:\n",len(unique_words))
# 3. 构建词嵌入层
# num_embeddings: 表示词的总数量
# embedding_dim: 表示词嵌入的维度
embed = nn.Embedding(num_embeddings=len(unique_words), embedding_dim=4)
print("词嵌入的结果:\n",embed)
# 4. 词语的词向量表示
for i, word in enumerate(unique_words):
# 获得词嵌入向量
word_vec = embed(torch.tensor(i))
print('%s\t' % word, word_vec)

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
文本分词: ['北京', '冬奥', '的', '进度条', '已经', '过半', ',', '不少', '外国', '运动员', '在', '完成', '自己', '的', '比赛', '后', '踏上', '归途', '。']
去重后词的个数:
18
词嵌入的结果:
Embedding(18, 4)
北京 tensor([-1.8043, 1.7860, -0.7821, -0.3167], grad_fn=<EmbeddingBackward0>)
的 tensor([-1.4856, -0.5639, 0.2745, 0.1087], grad_fn=<EmbeddingBackward0>)
冬奥 tensor([ 0.6969, -0.5615, 1.6524, -0.2651], grad_fn=<EmbeddingBackward0>)
自己 tensor([1.7163, 0.9710, 0.0193, 1.4562], grad_fn=<EmbeddingBackward0>)
不少 tensor([ 0.8770, -1.0347, 0.4939, 1.6718], grad_fn=<EmbeddingBackward0>)
归途 tensor([ 0.0619, 0.0355, -1.6510, 0.8121], grad_fn=<EmbeddingBackward0>)
比赛 tensor([-1.7128, 0.0681, 2.4199, 0.2714], grad_fn=<EmbeddingBackward0>)
进度条 tensor([-0.6706, 0.4089, -0.5371, 0.1093], grad_fn=<EmbeddingBackward0>)
外国 tensor([ 0.5665, -0.3168, -0.2065, 0.7682], grad_fn=<EmbeddingBackward0>)
完成 tensor([ 1.4640, -0.2800, -0.2242, -0.3790], grad_fn=<EmbeddingBackward0>)
过半 tensor([ 1.8026, 0.9831, -0.7177, 0.6779], grad_fn=<EmbeddingBackward0>)
踏上 tensor([-1.0745, -0.2610, -1.5350, -0.1767], grad_fn=<EmbeddingBackward0>)
运动员 tensor([1.8748, 0.2093, 1.9471, 0.3893], grad_fn=<EmbeddingBackward0>)
, tensor([-1.2841, -0.0675, -0.1263, -0.6892], grad_fn=<EmbeddingBackward0>)
在 tensor([ 0.6202, -0.0106, 1.0504, 0.0299], grad_fn=<EmbeddingBackward0>)
已经 tensor([2.4461, 0.2113, 0.9387, 0.1680], grad_fn=<EmbeddingBackward0>)
后 tensor([-1.1989, 0.8727, -0.9484, 0.0578], grad_fn=<EmbeddingBackward0>)
。 tensor([0.4020, 0.7357, 0.3571, 1.2355], grad_fn=<EmbeddingBackward0>)

3 循环网络层

文本数据是具有序列特性的,例如: “我爱你”, 这串文本就是具有序列关系的,”爱” 需要在 “我” 之后,”你” 需要在 “爱” 之后, 如果颠倒了顺序,那么可能就会表达不同的意思。

为了表示出数据的序列关系,我们需要使用循环神经网络(Recurrent Nearal Networks, RNN) 来对数据进行建模,RNN 是一个具有记忆功能的网络,它作用于处理带有序列特点的样本数据。

3.1 RNN网络层原理

当我们希望使用循环网络来对 “我爱你” 进行语义提取时,RNN计算过程是什么样的呢?

1755689365231

上图中h表示==隐藏状态==,隐藏状态保存了序列数据中的历史信息,并将这些信息传递给下一个时间步,从而允许RNN处理和预测序列数据中的元素。

每一次的输入都会包含两个值:上一个时间步的隐藏状态、当前状态的输入值x

每一次的输出都会包含两个值:输出当前时间步的隐藏状态、当前时间步的预测结果y

隐藏状态作用:

  • 记忆功能:隐藏状态就像RNN的记忆,它能够在不同的时间步之间传递信息。当一个新的输入进入网络时,当前的隐藏状态会结合这个新输入来生成新的隐藏状态。

  • 上下文理解:由于隐藏状态携带了过去的信息,它可以用于理解和生成与上下文相关的输出。这对于语言模型、机器翻译等任务尤其重要。

  • 连接不同时间步:隐藏状态通过网络内部的循环连接将各个时间步连接起来,使得网络可以处理变长的序列数据。

上图中,为了更加容易理解,虽然画了 3 个神经元, 但是实际上只有一个神经元,”我爱你” 三个字是重复输入到同一个神经元中。

1755689382437

我们举个例子来理解上图的工作过程,假设我们要实现文本生成,也就是输入 “我爱” 这两个字,来预测出 “你”,其如下图所示:

1755689395161

将上图展开成不同时间步的形式,如下图所示:

1755689405341

首先初始化出第一个隐藏状态,一般都是全0的一个向量,然后将 “我” 进行词嵌入,转换为向量的表示形式,送入到第一个时间步,然后输出隐藏状态 h1,然后将 h1 和 “爱” 输入到第二个时间步,得到隐藏状态 h2, 将 h2 送入到全连接网络,得到 “你” 的预测概率。

RNN神经元内部是如何计算的呢?

**1. 计算隐藏状态:**每个时间步的隐藏状态$$h_t$$是根据当前输入$$x_t$$和前一时刻的隐藏状态$$h_{t-1}$$计算的。

1755689419074

上述公式中:

  • $$W_{ih}$$ 表示输入数据的权重
  • $$b_{ih}​$$ 表示输入数据的偏置
  • $$W_{hh}​$$ 表示输入隐藏状态的权重
  • $$b_{hh}$$ 表示输入隐藏状态的偏置
  • $$h_{t-1}$$ 表示输入隐藏状态
  • $$h_t​$$ 表示输出隐藏状态

最后对输出的结果使用tanh激活函数进行计算,得到该神经元你的输出隐藏状态。

**2. 计算当前时刻的输出:**网络的输出$$y_t$$是当前时刻的隐藏状态经过一个线性变换得到的。

​ $$y_t=W_{hy}h_t+b_y​$$

  • $$y_t​$$ 是当前时刻的输出(通常是一个向量,表示当前时刻的预测值,RNN层的预测值)
  • $$h_t​$$ 是当前时刻的隐藏状态
  • $$W_{hy}$$ 是从隐藏状态到输出的权重矩阵
  • $$b_y$$ 是输出层的偏置项

3. 词汇表映射:输出$$y_t$$是一个向量,该向量经过全连接层后输出得到最终预测结果$$y_{pred}$$,$$y_{pred}$$中每个元素代表当前时刻生成词汇表中某个词的得分(或概率,通过激活函数:如softmax)。==词汇表有多少个词,$$y_{pred}$$就有多少个元素值,最大元素值对应的词就是当前时刻预测生成的词。==

神经元工作机制总结:

  • 接收输入:每个RNN神经元接收来自输入数据$$x_t$$和前一时刻的隐藏状态$$h_{t-1}$$。

  • 更新隐藏状态:神经元通过一个加权和(由权重矩阵和偏置项组成)更新当前时刻的隐藏状态$$h_t​$$,该隐藏状态包含了来自过去的记忆以及当前输入的信息。

  • 输出计算:基于当前隐藏状态$$h_t​$$,神经元生成当前时刻的输出$$y_t​$$,该输出可以用于任务的最终预测。

    1755689431951

文本生成示例:

假设我们使用RNN进行文本生成,输入是一个初始词语或一段上下文(例如,“m”)。RNN会通过隐藏状态逐步生成下一个词的概率分布,然后根据概率选择最可能的下一个词。

1755689442099

  1. 输入:“m” → 词向量输入$$x_1$$(对应“m”)

  2. 初始化隐藏状态$$h_0​$$,一般初始值为0

  3. 隐藏状态更新$$h_1​$$,并计算输出$$y_1​$$

  4. 经过全连接层输出层计算输出$$y_{pred}​$$,使用softmax函数将$$y_{pred}​$$转换为概率分布

  5. 选择概率最高的词作为输出词(例如“a”)

  6. 输入新的词“a”,继续处理下一个时间步,直到生成完整的词或句子

**小结:**在循环神经网络中,词与输出的对应关系通常通过以下几个步骤建立

  1. 词嵌入:将词转化为向量表示(词向量)。
  2. RNN处理:通过RNN层逐步处理词向量,生成每个时间步的隐藏状态。
  3. 输出映射:通过线性变换将隐藏状态映射到输出,通常是一个词汇表中的词的概率分布。

3.2 PyTorch RNN层的使用

  • API介绍

    1
    RNN = nn.RNN(input_size, hidden_size,num_layers)

    参数意义是:

    • input_size:输入数据的维度,一般设为词向量的维度
    • hidden_size:隐藏层h的维度,也是当前层神经元的输出维度
    • num_layers: 隐藏层h的层数,默认为1
  • 输入数据和输出结果

    将RNN实例化就可以将数据送入其中进行处理,处理的方式如下所示:

    1
    output, hn = RNN(x, h0)
    • 输入数据:主要包括词嵌入的x 、初始的隐藏层h0
      • x的表示形式为[seq_len, batch, input_size],即[句子的长度,batch的大小,词向量的维度]
      • h0的表示形式为[num_layers, batch, hidden_size],即[隐藏层的层数,batch的大小,隐藏层h的维度]
    • 输出结果:主要包括输出结果output,最后一层的hn
      • output的表示形式与输入x类似,为[seq_len, batch, input_size],即[句子的长度,batch的大小,输出向量的维度]
      • hn的表示形式与输入h0一样,为[num_layers, batch, hidden_size],即[隐藏层的层数,batch的大,隐藏层h的维度]
  • API使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import torch
    import torch.nn as nn


    # RNN层送入批量数据
    def test():
    # 词向量维度 128, 隐藏向量维度 256
    rnn = nn.RNN(input_size=128, hidden_size=256)
    # 第一个数字: 表示句子长度,也就是词语个数
    # 第二个数字: 批量个数,也就是句子的个数
    # 第三个数字: 词向量维度
    inputs = torch.randn(5, 32, 128)
    hn = torch.zeros(1, 32, 256)
    # 获取输出结果
    output, hn = rnn(inputs, hn)
    print("输出向量的维度:\n",output.shape)
    print("隐藏层输出的维度:\n",hn.shape)


    if __name__ == '__main__':
    test()

    输出结果:

    1
    2
    3
    4
    输出向量的维度:
    torch.Size([5, 32, 256])
    隐藏层输出的维度:
    torch.Size([1, 32, 256])

4 文本生成案例

文本生成任务是一种常见的自然语言处理任务,输入一个开始词能够预测出后面的词序列。本案例将会使用循环神经网络来实现周杰伦歌词生成任务。

1755689456314

4.1 导入工具包

1
2
3
4
5
6
import torch
import jieba
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.optim as optim
import time

4.2 数据集

我们收集了周杰伦从第一张专辑《Jay》到第十张专辑《跨时代》中的歌词,来训练神经网络模型,当模型训练好后,我们就可以用这个模型来创作歌词。数据集如下:

1
2
3
4
5
6
7
8
9
10
11
想要有直升机
想要和你飞到宇宙去
想要和你融化在一起
融化在宇宙里
我每天每天每天在想想想想著你
这样的甜蜜
让我开始相信命运
感谢地心引力
让我碰到你
漂亮的让我面红的可爱女人
...

该数据集共有 5819 行文本。

4.3 构建词表

在进行自然语言处理任务之前,首要做的就是构建词表。

所谓的词表就是将语料进行分词,然后给每一个词分配一个唯一的编号,便于我们送入词嵌入层。

1755689468815

接下来, 我们对周杰伦歌词的数据进行处理构建词表,具体流程如下:

  • 获取文本数据
  • 分词,并进行去重
  • 构建词表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 获取数据,并进行分词,构建词表
def build_vocab():
# 数据集位置
file_name = 'data/jaychou_lyrics.txt'
# 分词结果存储位置
# 唯一词列表
unique_words = []
# 每行文本分词列表
all_words = []
# 遍历数据集中的每一行文本
for line in open(file_name, 'r', encoding='utf-8'):
# 使用jieba分词,分割结果是一个列表
words = jieba.lcut(line)
# print(words)
# 所有的分词结果存储到all_words,其中包含重复的词组
all_words.append(words)
# 遍历分词结果,去重后存储到unique_words
for word in words:
if word not in unique_words:
unique_words.append(word)
# 语料中词的数量
word_count = len(unique_words)
# 词到索引映射
word_to_index = {word: idx for idx, word in enumerate(unique_words)}
# 歌词文本用词表索引表示
corpus_idx = []
# 遍历每一行的分词结果
for words in all_words:
temp = []
# 获取每一行的词,并获取相应的索引
for word in words:
temp.append(word_to_index[word])
# 在每行词之间添加空格隔开
temp.append(word_to_index[' '])
# 获取当前文档中每个词对应的索引
corpus_idx.extend(temp)
return unique_words, word_to_index, word_count, corpus_idx


if __name__ == "__main__":
# 获取数据
unique_words, word_to_index, unique_word_count, corpus_idx = build_vocab()
print("词的数量:\n",unique_word_count)
print("去重后的词:\n",unique_words)
print("每个词的索引:\n",word_to_index)
print("当前文档中每个词对应的索引:\n",corpus_idx)

我们的词典主要包含了:

  • unique_words: 存储了每个词

  • word_to_index: 存储了词到编号的映射

    1755689482659

4.4 构建数据集对象

我们在训练的时候,为了便于读取语料,并送入网络,所以我们会构建一个Dataset对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class LyricsDataset(torch.utils.data.Dataset):
def __init__(self, corpus_idx, num_chars):
# 文档数据中词的索引
self.corpus_idx = corpus_idx
# 每个句子中词的个数
self.num_chars = num_chars
# 文档数据中词的数量,不去重
self.word_count = len(self.corpus_idx)
# 句子数量
self.number = self.word_count // self.num_chars

# len(obj)时自动调用此方法
def __len__(self):
# 返回句子数量
return self.number

# obj[idx]时自动调用此方法
def __getitem__(self, idx):
# idx指词的索引,并将其修正索引值到文档的范围里面
"""
我 爱你 中国 , 亲爱 的 母亲
word_count: 7
num_chars: 2 一个句子由num_chars个词组成
word_count-num_chars-2: 7-2-1=4 -1:网络预测结果y在x上后移一个词取值-1
idx=5->start=4
"""
start = min(max(idx, 0), self.word_count - self.num_chars - 1)
end = start + self.num_chars
# 输入值
x = self.corpus_idx[start: end]
# 网络预测结果(目标值)
y = self.corpus_idx[start + 1: end + 1]
# 返回结果
return torch.tensor(x), torch.tensor(y)


if __name__ == "__main__":
# 获取数据
unique_words, word_to_index, unique_word_count, corpus_idx = build_vocab()
# 数据获取实例化
dataset = LyricsDataset(corpus_idx, 5)
# 查看句子数量
print('句子数量:', len(dataset))
# x, y = dataset.__getitem__(0)
x, y = dataset[0]
print("网络输入值:", x)
print("目标值:", y)

输出结果:

1
2
3
句子数量: 9827
网络输入值: tensor([ 0, 1, 2, 3, 40])
目标值: tensor([ 1, 2, 3, 40, 0])

4.5 构建网络模型

我们用于实现《歌词生成》的网络模型,主要包含了三个层:

  • 词嵌入层: 用于将语料转换为词向量

  • 循环网络层: 提取句子语义

  • 全连接层: 输出对词典中每个词的预测概率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 模型构建
class TextGenerator(nn.Module):
def __init__(self, unique_word_count):
super(TextGenerator, self).__init__()
# 初始化词嵌入层: 语料中词的数量, 词向量的维度为128
self.ebd = nn.Embedding(unique_word_count, 128)
# 循环网络层: 词向量维度128, 隐藏向量维度256, 网络层数1
self.rnn = nn.RNN(128, 256, 1)
# 输出层: 特征向量维度256与隐藏向量维度相同, 词表中词的个数
self.out = nn.Linear(256, unique_word_count)

def forward(self, inputs, hidden):
# 输出维度: (batch, seq_len, 词向量维度128)
# batch:句子数量
# seq_len: 句子长度, 每个句子由多少个词 词数量
embed = self.ebd(inputs)
# rnn层x的表示形式为(seq_len, batch, 词向量维度128)
# output的表示形式与输入x类似,为(seq_len, batch, 词向量维度256)
# 前后的hidden形状要一样, 所以DataLoader加载器的batch数要能被整数
output, hidden = self.rnn(embed.transpose(0, 1), hidden)
# 全连接层输入二维数据, 词数量*词维度
# 输入维度: (seq_len*batch, 词向量维度256)
# 输出维度: (seq_len*batch, 语料中词的数量)
# output: 每个词的分值分布,后续结合softmax输出概率分布
output = self.out(output.reshape(shape=(-1, output.shape[-1])))
# 网络输出结果
return output, hidden

def init_hidden(self, bs):
# 隐藏层的初始化:[网络层数, batch, 隐藏层向量维度]
return torch.zeros(1, bs, 256)


if __name__ == "__main__":
# 获取数据
unique_words, word_to_index, unique_word_count, corpus_idx = build_vocab()
model = TextGenerator(unique_word_count)
for named, parameter in model.named_parameters():
print(named)
print(parameter)

4.6 构建训练函数

前面的准备工作完成之后, 我们就可以编写训练函数。训练函数主要负责编写数据迭代、送入网络、计算损失、反向传播、更新参数,其流程基本较为固定。

由于我们要实现文本生成,文本生成本质上,输入一串文本,预测下一个文本,也属于分类问题,所以,我们使用多分类交叉熵损失函数。优化方法我们学习过 SGB、AdaGrad、Adam 等,在这里我们选择学习率、梯度自适应的 Adam 算法作为我们的优化方法。

训练完成之后,我们使用 torch.save 方法将模型持久化存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def train():
# 构建词典
unique_words, word_to_index, unique_word_count, corpus_idx = build_vocab()
# 数据集 LyricsDataset对象,并实现了 __getitem__ 方法
lyrics = LyricsDataset(corpus_idx=corpus_idx, num_chars=32)
# 查看句子数量
# print(lyrics.number)
# 初始化模型
model = TextGenerator(unique_word_count)
# 数据加载器 DataLoader对象,并将lyrics dataset对象传递给它
lyrics_dataloader = DataLoader(lyrics, shuffle=True, batch_size=5)
# 损失函数
criterion = nn.CrossEntropyLoss()
# 优化方法
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# 训练轮数
epoch = 10
for epoch_idx in range(epoch):
# 训练时间
start = time.time()
iter_num = 0 # 迭代次数
# 训练损失
total_loss = 0.0
# 遍历数据集 DataLoader 会在后台调用 dataset.__getitem__(index) 来获取每个样本的数据和标签,并将它们组合成一个 batch
for x, y in lyrics_dataloader:
# 隐藏状态的初始化
hidden = model.init_hidden(bs=5)
# 模型计算
output, hidden = model(x, hidden)
# 计算损失
# y形状为(batch, seq_len), 需要转换成一维向量->160个词的下标索引
# output形状为(seq_len, batch, 词向量维度)
# 需要先将y进行维度交换(和output保持一致)再改变形状
y = torch.transpose(y, 0, 1).reshape(shape=(-1,))
loss = criterion(output, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
iter_num += 1 # 迭代次数加1
total_loss += loss.item()
# 打印训练信息
print('epoch %3s loss: %.5f time %.2f' % (epoch_idx + 1, total_loss / iter_num, time.time() - start))
# 模型存储
torch.save(model.state_dict(), 'model/lyrics_model_%d.pth' % epoch)


if __name__ == "__main__":
train()

输出结果:

1
2
3
4
5
6
7
8
9
10
epoch   1 loss: 1.84424 time 5.75
epoch 2 loss: 0.21154 time 5.91
epoch 3 loss: 0.12014 time 5.85
epoch 4 loss: 0.10625 time 5.73
epoch 5 loss: 0.10226 time 5.58
epoch 6 loss: 0.10009 time 5.65
epoch 7 loss: 0.09942 time 5.66
epoch 8 loss: 0.09783 time 5.66
epoch 9 loss: 0.09663 time 5.75
epoch 10 loss: 0.09568 time 5.77

4.7 构建预测函数

从磁盘加载训练好的模型,进行预测。预测函数,输入第一个指定的词,我们将该词输入网路,预测出下一个词,再将预测的出的词再次送入网络,预测出下一个词,以此类推,知道预测出我们指定长度的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def predict(start_word, sentence_length):
# 构建词典
unique_words, word_to_index, unique_word_count, _ = build_vocab()
# 构建模型
model = TextGenerator(unique_word_count)
# 加载参数
model.load_state_dict(torch.load('model/lyrics_model_10.pth'))
# 隐藏状态
hidden = model.init_hidden(bs=1)
# 将起始词转换为索引
word_idx = word_to_index[start_word]
# 产生的词的索引存放位置
generate_sentence = [word_idx]
# 遍历到句子长度,获取每一个词
for _ in range(sentence_length):
# 模型预测
output, hidden = model(torch.tensor([[word_idx]]), hidden)
# 获取预测结果
word_idx = torch.argmax(output)
generate_sentence.append(word_idx)
# 根据产生的索引获取对应的词,并进行打印
for idx in generate_sentence:
print(unique_words[idx], end='')


if __name__ == '__main__':
# 调用预测函数
predict('分手', 50)

输出结果:

1
2
3
4
5
6
分手的话像语言暴力
我已无能为力再提起 决定中断熟悉
周杰伦 周杰伦
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线背著背默默许下心愿
看远方的星

大模型应用初体验与聊天机器人的项目

今日大纲介绍

今日目标:掌握使用VMware+CentOS搭建聊天机器人项目环境

核心知识点模块:

①聊天机器人项目介绍

②大模型核心基础

③VM安装与Linux使用

④聊天机器人部署项目环境

【熟悉】聊天机器人项目简介

学习目标

掌握聊天机器人搭建核心步骤,完成聊天机器人架构设计

什么是聊天机器人

  • 概念:聊天机器人是一种基于人工智能的自然语言处理技术开发的软件程序,能够通过文本或语音与用户进行交互,模拟人类对话。它可以根据用户输入的问题或指令,生成相应的回答或执行特定的操作。

20250219235132

  • 特点:

    1. 自然语言理解(NLP):能够理解用户输入自然语言,包括文字或语音,并从中提取意图和关键信息。

      1. 人工智能 人工智障
    2. 对话管理:通过对话引擎维持对话的连贯性,根据上下文生成合适的回答。

    3. 个性化交互:可以根据用户的历史记录和偏好提供定制化的回答。

      ​ 笔记本 电脑 真笔记本

    4. 多功能性:除了聊天,还可以执行任务,如查询信息、预订服务、提供帮助等。

      1. ​ 执行任务
      2. ​ 查询信息
      3. ​ 预订服务
  • 应用场景:

    1. 客户服务:在电商、金融等领域,聊天机器人可以自动解答用户问题,提供24*7的客户支持。

      1.

    2. 娱乐:一些聊天机器人可以与用户进行趣味对话,提供娱乐体验。

    3. 教育:用于语言学习、知识问答等教育场景。

      1.

    4. 智能家居:控制家电设备,如灯光、空调等。

      ​ 智能音箱

      ​ 扫地机器人

    5. 医疗健康:提供健康咨询、预约挂号等服务。

      1. ​ AI +图形 (误诊率) 辅助
  • 有哪些常见聊天机器人?

    DeepSeek

    由杭州深度求索人工智能基础技术研究有限公司研发, 其核心优势在于性能卓越、低成本开发和开源策略

    Kimi智能助手
    由月之暗面科技有限公司开发,支持超长上下文(最高200万汉字),适合长文本处理和复杂对话。

    通义千问
    阿里云推出的人工智能助手,适合办公场景,提供高效的信息处理能力。

    讯飞星火
    科大讯飞出品,支持语音输入和语音朗读回复,适合语音交互场景。

    豆包
    字节跳动推出,支持抖音和今日头条的内容信息获取,适合内容创作和信息检索。

    上面部分聊天机器人后面会给大家演示功能。

  • 阿甘智能聊天机器人效果展示

    本次课我们会带领大家完成从0-1的聊天机器人搭建。

    1740671928092

    如何搭建像上面一样的聊天机器人?我们一起来看看基本需求

项目需求分析

项目旨在构建一个基于大模型的智能聊天机器人,利用其强大的自然语言处理和生成能力,为用户提供高效、精准、个性化的对话服务。

该聊天机器人将集成先进的大规模预训练语言模型(如GPT、Qwen等),具备自然语言理解、多轮对话、情感分析、知识问答等核心功能,并可根据具体应用场景进行定制化扩展,如客服咨询、教育辅导、娱乐互动等。

相关功能需求如下:

(一)核心对话功能需求

  1. 自然语言处理
    • 聊天机器人能够理解和生成自然语言文本,支持中文和英文对话。
    • 能够处理用户的输入并生成==准确、流畅==的回复。
  2. 实时对话交互
    • 用户可以通过 Streamlit 界面输入文本,聊天机器人实时响应并展示回复。
    • 对话过程流畅,延迟时间不超过 3 秒。

(二)用户界面功能需求

  1. 简洁明了的布局
    • 提供输入框、发送按钮和对话展示区域。
    • 界面设计简洁美观,易于操作。
  2. 交互式体验
    • 用户输入问题后,点击发送按钮即可触发对话。
    • 聊天机器人的回复实时展示在对话区域。

根据上述功能需求,项目采用模块化设计,前端通过Streamlit等框架实现简洁易用的交互界面,后端基于Ollama等平台进行模型部署和管理,确保系统的高效性和可扩展性。

项目目标旨在开发一款基于自然语言处理技术的聊天机器人,能够通过网页界面与用户进行实时对话,为用户提供高效、便捷的交互体验。

了解了相关需求之后,如何搭建聊天机器人呢?我们一起看看有哪些方式?

如何搭建聊天机器人

常见搭建聊天机器人方式有3种,通常根据功能会结合其中1-2种实现聊天机器人搭建,3种方式分别是:

①使用无代码平台搭建

②使用开源框架开发

③基于大语言模型的集成

使用无代码平台搭建

无代码平台允许用户通过可视化界面快速创建聊天机器人,无需编程基础。例如,扣子(Coze) 是一个由字节跳动开发的智能体应用开发平台,支持集成多种大语言模型(如 DeepSeek),并可以快速接入微信公众号。

搭建步骤:

  1. 注册并登录平台:访问 扣子官网,使用抖音或飞书扫码登录。
  2. 创建应用:填写智能体名称、功能介绍和图标。
  3. 配置机器人
  • 选择模型(如 DeepSeek 或其他大模型)
  • 添加插件(如联网、绘画等)
  • 编写开场白并测试对话效果
  1. 接入平台:将机器人接入微信公众号或其他平台,配置必要的参数(如 AppID)

如果需求简单且希望快速上线,优先选择无代码平台。

使用开源框架开发

如果你有一定的编程基础,可以使用开源框架(如 ChatterBot)和 Web 框架(如 Flask)来开发聊天机器人

安装必要的库:安装 Flask 和 ChatterBot。

编写代码:创建一个 Flask 应用,集成 ChatterBot 并训练模型。

创建前端界面:使用 HTML 和 JavaScript 创建一个简单的聊天界面

部署应用:将应用部署到服务器,如 Heroku 或本地服务器。

ChatterBot 是一个开源的 Python 库,用于创建聊天机器人。它通过机器学习技术来生成对话内容,能够根据用户输入自动学习和生成回答。

ChatterBot库对话生成能力有限,生成文本可能不够自然,大模型出来之前使用较多

基于大语言模型的集成

如果你希望使用更强大语言模型(如 DeepSeek或QWen),可以通过本地部署或云服务快速搭建聊天机器人。

搭建步骤:

  1. 部署模型:使用 Ollama部署 QWen或DeepSeek。
  2. 配置机器人:通过 Ollama 的 API 配置聊天机器人,设置模型、对话历史等参数。
  3. 接入微信或其他平台:使用 Gewechat 框架将机器人接入微信。

适合有一定技术能力的企业,需要高度定制化功能的聊天机器人。

适合大模型出来后有更好对话效果场景,目前企业纷纷采用方式。

三种方式区别联系

  • 如果需求简单且希望快速上线,优先选择无代码平台。
  • 如果需求复杂,需要高度定制化功能,建议选择开源框架。
  • 如果需要高质量的对话体验且预算充足,可以选择基于大语言模型的集成。

当前项目我们选择基于开源框架和基于大语言模型集成的综合方式来开发聊天机器人,不仅能保障适合数据隐私和安全性要求,还可以实现高质量对话体验。接下来我们一起看项目方案

项目方案

这里我们采用综合的基于开源框架和编程开发方法来开发聊天机器人。具体来说,这种方法结合了后端模型(Ollama 平台的 Qwen, DeepSeek模型)和前端界面(Streamlit 框架)来实现聊天机器人的功能。这种方法需要一定的编程基础,但可以提供更高的灵活性和定制化能力。

后端模型:Ollama 平台的 Qwen 模型

  • 特点:基于 Ollama 平台部署 Qwen, DeepSeek模型作为后端核心,提供自然语言处理和对话生成能力。
  • 技术细节
    • Ollama 是一个开源的 AI 模型部署平台,支持多种大语言模型(LLM)。
    • Qwen 是一个高性能的语言模型,能够处理和生成自然语言文本。
    • 通过后端服务调用 Qwen 模型,将用户输入传递给模型,并获取模型的回复。

前端界面:Streamlit 框架

  • 特点:使用 Streamlit 框架搭建用户界面,提供简洁、交互式的 Web 应用。
  • 技术细节
    • Streamlit 是一个基于 Python 的开源框架,适合快速开发数据科学和机器学习相关的 Web 应用。
    • 你通过 Streamlit 创建了一个用户界面,包括输入框、发送按钮和对话展示区域。
    • 用户可以通过网页与聊天机器人进行实时对话。

对话交互与模型调用

  • 特点:后端服务负责将用户输入传递给 Qwen 模型,并将模型生成的回复返回给前端界面。
  • 技术细节
    • 你可能使用了 Python 编程语言来实现后端逻辑,将用户输入发送到 Qwen 模型,并处理模型的输出。
    • 这种方式需要编写代码来实现前后端的通信,确保对话的实时性和准确性。

项目架构设计

整体项目架构如下:

架构图0218

项目完整架构:

  • 后端模型:利用 Ollama 平台的 Qwen 模型,该模型具备出色的自然语言处理能力,能够理解和生成自然语言文本,为聊天机器人提供核心的对话处理功能。
  • 前端界面:采用 Streamlit 框架搭建用户界面,Streamlit 是一个简单易用的 Python 库,能够快速创建美观、交互式的 Web 应用,使用户能够通过网页与聊天机器人进行实时对话。
  • 对话交互:用户可以通过 Streamlit 界面输入文本,聊天机器人基于 Qwen 模型对输入内容进行理解和处理,生成相应的回复并展示在界面上,实现流畅的对话交互。
  • 模型调用:后端服务负责将用户输入传递给 Qwen 模型,并获取模型生成的回复,然后将回复内容返回给前端界面进行展示,确保对话的实时性和准确性。
  • 界面展示:Streamlit 界面提供简洁明了的布局,包括输入框、发送按钮和对话展示区域,用户可以方便地输入问题并查看机器人的回答,提升用户体验。

小结

Q1:搭建聊天机器人方法?

  • 无代码平台搭建
  • 开源框架开发
  • 基于大语言模型的集成

Q2:聊天机器人搭建核心有哪几步?

  • 1:完成Ollama平台部署
  • 2:调用Qwen2大模型,完成基座模型构建
  • 3:采用Streamlit构建聊天机器人前端页面

【熟悉】大模型核心基础

学习目标

掌握大模型(Lager Language Model,LLM)应用场景及核心运行机制(了解),为搭建聊天机器人应用奠定理论基础

大模型分类

自然语言处理模型

专注于文本生成、理解、翻译等任务,GPT系列(OpenAI)、BERT(Google)、T5(Google)

1739844636699

计算机视觉(CV)模型

视觉大模型(Large Visual Models)核心是通过大规模数据和复杂模型架构,实现对图像和视频的深度理解和生成。与传统计算机视觉模型相比,视觉大模型具有更强的泛化能力和多任务适应性,能够处理复杂的视觉任务,如图像分类、目标检测、语义分割、图像生成等。

Stable Diffusion、Vision Transformers (ViT)、DALL·E(OpenAI)、CLIP(OpenAI)

1739844687590

语音模型

语音大模型是基于深度学习技术构建的人工智能模型,主要用于处理语音相关的任务,如语音识别(ASR)、语音合成(TTS)、语音翻译等。近年来,随着深度学习和大规模数据训练的发展,语音大模型在性能和功能上取得了显著进展,能够支持多语言、多场景的复杂任务。

举例:Whisper(OpenAI)、WaveNet(DeepMind)、讯飞星火

Whisper 由 OpenAI 开发的开源多语言语音识别模型,支持多种语言的语音转录和翻译

讯飞星火由科大讯飞推出的语音大模型,尤其在中文语音识别方面表现突出,支持多种方言和少数民族语言。此外,讯飞星火还具备强大的语音合成能力。

语音模型‌是一种将声音信号转换为数字信号的模型。

image-20250219123303136

语音模型的应用场景

  1. 语音识别‌:将人类语音转换为文本或其他可理解的形式,广泛应用于智能助手、语音输入和自动化客服系统。
  2. 语音合成‌:生成自然、具备韵律且富有情感的语音,适用于多语言、情感丰富的TTS应用。
  3. 语音增强‌:提高语音信号的清晰度和质量,常用于噪声环境下的语音处理。
  4. 声音事件监测‌:识别环境中的特定声音事件,如警报声、机器故障声等。
  5. 说话人识别‌:识别说话人的身份,常用于安全验证和个性化服务。

多模态模型

多模态模型是一种能够同时处理多种数据模态(如文本、图像、音频、视频等)的人工智能模型。与传统的单模态模型(如仅处理文本或图像)相比,多模态模型通过整合不同模态的数据,能够提供更全面、更准确的理解和生成能力。这些模型在多个领域展现出强大的应用潜力,例如医疗诊断、自动驾驶、智能助手等。

多模态模型的核心在于跨模态融合,即将不同模态的数据表示映射到同一空间,以便模型能够理解和生成跨模态的内容。例如,在视觉问答(VQA)任务中,模型需要同时理解图像内容和自然语言问题,以生成准确的答案。

举例:GPT-4(支持多模态)、Flamingo(DeepMind)、BLIP、KOSMOS(微软)

image-20250219123333756

对图解释如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
这里展示了一个基础模型(Foundation Model)如何通过训练和适应(Adaptation)处理不同类型的数据,并执行多种任务。以下是图中各部分的详细解释:
数据(Data)
基础模型的训练需要多种类型的数据,这些数据包括:
文本(Text):包括书籍、文章、网页等文本信息。
图像(Images):包括照片、插图、图表等视觉信息。
语音(Speech):包括语音记录、音频文件等声音信息。
结构化数据(Structured Data):包括数据库中的表格数据、电子表格等。
3D信号(3D Signals):可能包括3D模型、点云数据等三维信息。

训练(Training)
使用上述数据对基础模型进行训练,使其能够理解和处理不同类型的信息。

基础模型(Foundation Model)
训练完成后,基础模型能够执行多种任务,并通过适应过程进一步优化其性能。

适应(Adaptation)
基础模型可以通过适应过程针对特定任务进行优化,以提高其在特定应用场景下的表现。

任务(Tasks)
基础模型可以执行以下任务:
问答(Question Answering):回答用户的问题。
情感分析(Sentiment Analysis):分析文本中的情感倾向,如正面、负面或中性。
信息提取(Information Extraction):从文本中提取关键信息,如实体、关系等。
图像描述生成(Image Captioning):为图像生成描述性文本。
物体识别(Object Recognition):识别图像中的物体。
指令遵循(Instruction Following):根据用户的指令执行特定的任务。

这里展示了基础模型的强大能力,它可以通过训练和适应处理多种类型的数据,并执行广泛的任务,从而在各种应用场景中发挥作用。

大模型应用场景

  • 智能客服与对话系统:用于构建聊天机器人、虚拟助手,提供24*7的客户支持。目前大模型最广泛应用。
  • 文本生成:生成文章、故事、代码、营销文案等。
  • 机器翻译:实现多语言之间的高质量翻译。
  • 问答系统:提供精准的问答服务,如知识库查询、技术支持。
  • 图像分类与识别:识别图像中的物体、场景或人脸。
  • 目标检测与跟踪:用于自动驾驶、安防监控等场景。
image-20250219123036053

热门大模型初体验

这里主要包括讯飞星火及阿里通义千问大模型使用。

讯飞星火认知大模型

科大讯飞推出的新一代认知智能大模型,拥有跨领域的知识和语言理解能力,能够基于自然对话方式理解与执行任务。例如:语言理解、知识问答、逻辑推理、数学题解答、代码理解与编写。

1736732220988

  • 场景一:编写报告&计划

    1736734287717

  • 场景二:朋友圈&简历书写

    1736734373135

阿里通义大模型

通义千问是阿里巴巴推出的一款大型预训练语言模型,它能够回答问题、创作文字,还能表达观点、撰写代码。基于海量数据训练,通义千问具备广泛知识和较强理解能力,致力于为用户提供精准、多样、有创意的回答,成为用户在学习、工作、生活中的智能助手。

1736730957613

  • 场景一:文本对话

    1736731081651

  • 场景二:指令中心

    什么是指令中心

    指令中心就是通义千问的一个插件库,输入/或者点击右侧按钮,就可以进入通义千问的指令中心了。

    1736731178773

  • 场景三:解题高手

    什么是解题高手

    你擅长回答学习问题并给出解题步骤,鉴于以下学习问题,请提供详细的回答并给出解题步骤:

    七人并排站成一行,如果甲乙两个必须不相邻,那么有几种排列方法

    1736731276775

  • 场景四:编程助手

    什么是编程助手

    你是一个Python代码的工程师,

    请解答我的问题:请基于 Python 写一个生成器代码,用于生成斐波那契数列

    1736731323913

DeepSeek

  • 背景

    DeepSeek是一家专注于人工智能和大数据技术的创新企业,致力于为各行业提供智能化解决方案。其核心产品包括智能客服系统、数据分析平台和个性化推荐引擎,帮助企业提升运营效率、优化用户体验。

  • 优势

    低成本:DeepSeek在训练和使用成本方面具有显著优势。DeepSeek-V3的训练成本仅为557万美元,远低于行业平均水平,成为开源模型中的“性价比之王”。

    开源性:DeepSeek采取了开源策略,允许全球开发者社区检查、改进并利用这些模型进行进一步的研究和开发。这不仅促进了知识的共享和技术的进步,还为开发者提供了广阔的商用空间。

20250220001044

大模型核心运行机制

大模型的核心运行机制基于深度学习,尤其是Transformer架构。其核心是自注意力机制,能够捕捉输入序列中不同部分的关系。模型通过预训练在大规模数据上学习语言规律,再通过微调适应特定任务。训练过程中,使用反向传播和优化算法(如Adam)调整数百万甚至数十亿的参数。依赖GPU/TPU等高性能硬件和分布式训练加速计算。输入文本经过分词与嵌入转换为向量表示,模型通过推理生成输出,并采用生成策略(如束搜索)确保输出质量。整个过程依赖大规模数据和计算资源,实现复杂的语言理解和生成能力。核心架构图如下:

image-20250219121053249

核心模型树如下:

image-20250219121231347

大模型是怎么演进的?

  • Encoder Only: 对应粉色分支,即BERT派,典型模型: BERT

    • 自编码模型(Autoencoder Model):通过重建句子来进行预训练,通常用于理解任务,如文本分类和阅读理解。
    • 模型像一个善于分析故事的专家,输入一段文本,能拆解的头头是道,本质上是把高维数据压缩到低维空间。
  • Decoder Only: 对应蓝色分支,GPT派, 典型模型: GPT4,LLaMA,DeepSeek,QWen

    • 自回归模型(Autoregressive Model):通过预测序列中的下一个词来进行预训练,通常用于文本生成任务。
    • 模型像一个会讲故事的专家,给点提示,就能流畅的接着自说自话。
  • Encoder-Decoder: 对应绿色分支,T5派, 典型模型: T5, ChatGLM

    • 序列到序列模型(Sequence to Sequence Model):结合了编码器和解码器,通常用于机器翻译和文本摘要等任务。
    • 模型像一个“完型填空专家”,是因为它特别擅长处理这种类型的任务。通过将各种NLP任务统一转换为填空问题,T5派能够利用其强大的语言理解和生成能力来预测缺失的文本。这种方法简化了不同任务之间的差异,使得同一个模型可以灵活地应用于多种不同的NLP任务,并且通常能够在多个任务上取得很好的性能。

小结

Q1:大模型有那些分类?

  • 大语言模型、视觉大模型、语音大模型和多模态大模型

Q2:大模型有那些应用场景?

  • 机器翻译、文本生成、对话系统、聊天机器人等应用

【实操】VMware安装

学习目标

掌握大模型部署必备的VMWare+CentOS,完成虚拟机安装与配置

软件介绍

  • 虚拟化介绍

    虚拟机 (Virtual Machine) 指通过软件模拟的具有完整硬件系统功能的,运行在一个完全隔离环境中的完整计算机系统

  • 常用的虚拟化软件

    • VMware:虚拟机软件兼容性很强,快照功能很快捷,方便,允许你在任意开机时刻创建系统快照和恢复
    • VirtualBox:Sun公司的产品,属于轻量级的虚拟机平台,功能相对也很精简,快照功能这里叫备份和快速修复,在不同的快照间跳转用起来感觉不是很方便,也不能实现文件拖拽的功能。
  • 宿主机和虚拟机关系图

    1677642782873

VMware软件安装

参考提供给大家的详细安装文档, 我们已经装好了, 此处只强调两点.

  • 安装路径要合法, 不要出现中文, 空格, 特殊符号等.
  • 建议大家找1个路径, 统一管理, 例如: D:/SoftWare/VMware

搭建Linux虚拟机

参考提供给大家的详细安装文档, 此处只强调两点.

  • 记得手动修改IP为统一IP: 192.168.88.100, 网关为统一网关: 192.168.88.2
  • 修改账号信息统一为: root账号, 密码为: 123456

验证虚拟机搭建成功

  • 登陆

    1740674285642

  • 查看ip

    1740674346356

==注意: 此处的默认网关地址,和VMware虚拟网络适配器的网关地址要完全相同,否则虚拟机无法上网==

小结

Q1:如何在虚拟机中查看ip地址?

  • ifconfig

【掌握】Linux基础

学习目标

掌握Linux核心命令,为大模型私有化部署奠定基础

Linux系统概述

  • Linux发行时间: 1991年

  • Linux的创始人: 林纳斯·托瓦兹

  • Linux的吉祥物: 企鹅

  • 官网地址: https://www.kernel.org/

    Linux发行版 = Linux内核 + 系统库 + 系统软件

    Linux的内核完全开源免费, 但是Linux的发行版 不一定免费

  • 常见的Linux发行版有哪些?

    • RedHat : 世界最大的Linux发行版厂商, 已经被IBM收购
    • Ubuntu: 桌面操作系统做的最好的
    • CentOS: 目前中国市场使用最多的Linux版本,目前已经被RedHat收购,但依然免费
    • Deepin: 深度公司开发的Linux版本.国内做的最好的Linux发行版
      1739856296312

Linux的目录结构

  • Linux和Windows, Mac一样, 都是文件系统, 采用文件 和 文件夹的形式来管理数据.
  • 只不过在Linux 操作系统中, 是没有盘符概念的, 任何文件(文件夹)都是从根目录开始进行拆分的

  • 且Linux中采用的是目录树结构, Windows中采用的是森系结构, 如下图:

    1677654690975

  • Linux中常用的目录结构:

    • /etc : 配置文件存放的目录, 相当于Windows中的设置面板

    • /home: 用户的家目录,相当于Windows中的用户目录

    • /opt: 应用程序存放的目录,相当于Windows中的 software目录

    • /bin: 终端指令集存放的目录

    • /sbin: 超级管理员用户使用的指令集,包括用户的创建删除等指令

    • /root: 超级管理员的家目录, 每个Linux系统默认有且只有一个超管用户,拥有该操作系统的一切权限,也是最高权限.

      666666666

Linux的常用命令

Linux指令的构成:

1
2
3
4
5
linux指令 = 命令(做什么) + 选项(怎么做) + 参数(对谁做)

- command : 命令名, 相应功能的英文单词或单词的缩写
- [-options] : 选项, 可用来对命令进行控制, 也可以省略
- parameter : 传给命令的参数, 可以是 零个、一个 或者 多个

Linux文件与目录管理

  • ls命令

    ls命令: 展示linux系统中指定位置的目录信息

    1
    2
    3
    -a  查看所有文件,包括隐藏文件
    -l 展示文件的详细信息,包括权限,归属,文件大小,创建修改时间,文件名称
    -h 人性化展示文件大小,赋予最恰当的单位

    ls 指令的三个选项可以随意自由组合,且选项的顺序可以随意调整

    1
    2
    3
    ls -lh  展示文件详细信息列表,并且合理展示单位
    ls -al 展示所有文件详细信息列表,包括隐藏文件
    ls -alh 展示所有文件详细信息列表,包括隐藏文件,并且合理展示单位

    ls 可以获取任意指定路径的文件信息

    1
    2
    3
    ls  参数  路径信息
    ls / 查看根目录的文件
    ls aaa 查看当前目录下的aaa目录中的文件内容

    ls -l 完全等价于 ll 可以快速查看文件的详细信息

    【拓展:】ll 也可以配合选项-h -a使用

  • Linux中的路径:

    什么是文件路径?

    ​ 路径就是我们从根目录,盘符或者指定位置,查找到目标文件所经历的目录层级.

    ​ 现实路径的描述方式:

    ​ 1.中国 北京市 昌平区 回龙观东大街 xxx校区 x号楼 x单元….
    ​ 2.从当前位置触发,向前行驶五公里,左转向前行驶4公里,掉头……

    计算机中路径的描述方式

    1. 绝对路径: 从根目录或者盘符出发,直到查找到目标文件所经历的目录层级
    2. 相对路径: 从当前目录出发,直到查找到目标文件所经历的目录层级
  • Linux中的路径和Windows中的路径有什么区别?

    绝对路径中, Linux 是从根目录出发进行查找, Windows是从盘符出发进行查找

  • Linux中路径的书写方式

    hello.py绝对路径: /root/apple/hello.py

    1677662356486

    从apple目录出发,到linux.java的相对路径: ../../home/java/linux.java

    1
    2
    ./  代表当前目录
    ../ 代表上一级目录
  • cd命令

    cd命令,是为了切换工作目录,或者说活动目录的

    例如:ls后不加任何参数,则默认输出当前目录的文件信息, cd命令就切换的是当前目录

    cd 路径信息 可以切换到指定目录中

    cd ../ 返回上一级目录

    cd - 返回上一次操作的工作目录

    cd / 进入根目录

    cd ~ 返回家目录, 波浪线可以省略

    注意: cd指令中 同样可以使用相对路径,也可以使用绝对路径

  • pwd命令

    pwd命令获取的就是当前所在的工作目录的绝对路径

    注意: pwd获取的是目录路径,不是文件路径 (==目录就等于文件夹==)

  • mkdir命令

    mkdir命令是创建空目录的命令,我们可以在指定路径下创建一个空目录

    1
    2
    3
    4
    5
    >mkdir 文件路径    在指定路径下创建目录
    >mkdir ./aaa

    >mkdir -p 文件路径 在指定路径下创建一个空目录,同时创建其父目录
    >mkdir -p ./111/222/333
  • touch命令

    touch 可以创建一个新的文件,文件的扩展名随意,甚至可以是不存在的扩展名

    touch 可以一次性创建多个文件,但是文件路径必须正确

    1
    touch 1.txt 2.txt 3.txt 

    touch创建的文件如果存在不报错,但是没有新文件产生

  • rm命令 remove

    rm 是删除文件的指令,可以删除文件或文件夹

    1
    2
    -r 递归删除,删除文件夹时使用
    -f 强制删除,不进行问询

    rm 可以删除任意文件,路径可以是相对路径,也可以是绝对路径

    1
    2
    3
    4
    5
    6
    # 删除文件
    rm /root/1.txt
    # 删除文件夹
    rm -r /root/aaa
    # 删除文件夹并不进行提示
    rm -rf /root/aaa

    rm可以一次性删除多个文件

    1
    2
    3
    4
    # rm后跟随多个路径
    rm 1.txt 2.txt 3.txt
    # rm后跟随路径通配符
    rm ./aaa/*

    在正常开发中如果使用的是root权限,不建议使用-f 如果必须使用,需要极其慎重,因为这种删除方式无法找回

Linux查看文件内容

  • cat指令

    用于查看linux中的小型文本文件

    因为他会一次性将所有的文件内容加载到终端中,终端的数据展示数量有限,大文件显示不全,且过于消耗内存

    1
    cat 文件名称
  • more指令

    用于查看linux中的中型文本文件

    使用more进行文件的查看可以按页显示,手动翻页或回滚,更加灵活,但同样消耗内存

    1
    2
    3
    4
    5
    more 文件名称
    - enter 向下一行
    - space 向下一页
    - b 向上一页
    - q 退出查看

    Linux文件打包和压缩文件

    • tar命令

      tar命令是进行打包,解包, 压缩和解压的命令

      打包: 将多个文件归档为一个文件,文件大小不会减小.

      解包(拆包):将一个包文件拆分为多个实体文件.

      压缩:将文件按照一定的算法减小体积,但是文件的内容和信息不发生改变

      解压:将一个压缩文件还原到正常状态.

      参数:

      • c : 打包选项
      • x : 解包选项
      • z : 压缩或者解压选项
      • v : 展示过程信息
      • f : 指定文件名称

      注意: c 和x 参数不能同时出现在终端命令中

      打包

      1
      2
      3
      4
      # tar -cvf 包的名称  要打包的文件列表
      tar -cvf 1_3.tar 1.txt 2.txt 3.txt
      # 将1.txt 2.txt 3.txt 打包到 aaa目录下
      tar -cvf aaa/1_3.tar 1.txt 2.txt 3.txt

      解包

      1
      2
      3
      4
      5
      6
      7
      # 将原有的.txt文件全部删除
      rm -f *.txt
      # 将1_3.tar 解压到当前压缩包所在位置
      tar -xvf 1_3.tar
      # 将个文件解压bbb目录下
      # 此时需要使用选项C(大写)指定解包路径
      tar -xvf 1_3.tar -C bbb

      压缩

      1
      tar -zcvf 1_3.tar 1.txt 2.txt 3.txt

      解压缩

      1
      tar -zxvf 1_3.tar -C bbb

      在开发中,我们一般使用的最多的是解压.解压指令可以记忆为长兄为父(zxvf)

      注意:

      1. 压缩时,如果源文件太小,可能体积会增大 例如 被压缩文件只有20B 可能压缩完成后大小是50B
      2. 压缩和解压时一般使用.tar.gz结尾,方便程序员交流
      3. 使用上述指令压缩后,文件为gzip压缩格式.

Linux文件基本属性

  • chmod命令

    chmod主要是进行文件权限管理的,可以给文件增加修改删除权限

    语法 chmod [-R] 权限 文件或者文件夹

    选项:-R,对文件夹内的全部内容应用同样的操作

  • 数值型权限管理

    权限可以用3位数字来代表,第一位数字表示用户权限(u),第二位表示用户组权限(g),第三位表示其它用户权限()。
    数字的细节如下:r记为4,w记为2,x记为1,可以有:

    421

    1
    2
    3
    4
    5
    6
    ># 用户拥有读写执行权限(rwx 7), 用户组拥有读写权限(rw 6), 其他用户拥有读的权限(r 4)
    >chmod 764 1.txt
    ># 如果需要所有用户具有可读可写可执行权限
    >chmod 777 1.t.xt

    ># 注意: 在开发中尽量不要出现777的权限会让别人觉得你很low 侮辱你的职业

    1739865684067

  • 字母型权限管理

    r : 读权限

    w : 写权限

    x : 执行权限

    u : 拥有者

    g : 用户组

    o : 其他用户

    a : 所有用户

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ># 格式: chmod - + 权限
    ># 给自己减少可执行权限,给用户组增加写入权限
    >chmod u-x,g+w abc
    ># 给所有用户减少读的权限
    >chmod a-r abc

    ># 格式: chmod = 权限
    ># 给自己设置属主权限为只读,此时原有权限全部消失,只保留新赋予的权限内容
    >chmod u=r abc
    ># 给所有用户最高权限
    >chmod a=rwx abc

    ># 格式: 混用
    ># 给用户读写执行权限, 给用户组读写权限, 给其他用户只读权限
    >chmod u=rwx,g-x,o-wx abc

    ># 如果我们需要修改当前目录及其目录中子文件的权限,需要使用递归方式完成操作 条件-R选项即可
    >chmod -R u=rwx,g=rw,o=r aaa

1739865856802

1739865999965

1739866038917

1739866074736

系统管理命令

  • ps命令

    查看linux系统中的进程信息

    1
    2
    ps  查看当前活跃进程
    ps -ef 查看当前所有进程

    在查看进程时,pid这一列中存储的是进程编号,也就是这个进程的唯一标识.
    1677725479917

  • kill命令

    如果我们想结束linux中的软件或服务也可以通过操作进程来解决

    1
    kill -9 进程编号

    注意:

    kill -9 可以快速杀死进程,但是不安全,因为我们的服务再运行过程中,可能会需要保存或者将某些任务执行完再关闭,所以轻易不用,一般都是用于杀死闲置进程,或者不响应的进程.

  • ifconfig命令

    ifconfig主要用于查看服务器的网络信息, 当前阶段最重要的信息就是ip地址

    1677726098779

    扩展:

    在windows中如果需要查看网卡信息,需要使用ipconfig进行查看

  • free命令

    可以使用free查看内存使用情况

    1677726358857

    1677726407717

  • df命令

    可以使用df命令查看磁盘的使用情况

    1677726495835

  • clear命令

    clear命令,可以清除终端窗口的信息,让光标移动到终端的最上方

    快速清屏也可以使用快捷键 ctrl + L

小结

Q1:Linux文件与目录管理命令有哪些?

  • ls、pwd、mkdir、touch、cd、rm

Q2:如何查看Linux中文件内容?区别是什么?

  • cat:主要用于显示整个文件内容,适合查看小文件
  • more:用于分页显示文件内容,适合查看大文件。

Q3:如何查看Linux系统进程命令?

  • ps:是 Linux 中用于查看当前系统进程状态的工具。它可以显示正在运行的进程信息,如进程 ID(PID)、CPU 和内存使用情况、运行状态等。

练习

cd命令

1
2
3
4
5
6
7
8
9
10
1:切换到你的主目录。

2:切换到根目录 (/)。

3:切换到上一级目录。

4:切换到名为 Documents 的目录,假设它在你的主目录下。

5:如果你在任意目录下,直接切换到 /var/log 目录。

mkdir命令

1
2
3
4
5
6
7
8
1:基础创建:在你的主目录下创建一个名为 NewFolder 的新目录。

2:创建多级目录:在同一命令中创建多级目录结构,例如 ~/NewFolder/SubFolder1/SubFolder2。

3:创建多个同级目录:在你的主目录下同时创建 FolderA, FolderB, 和 FolderC。

4:在特定目录下创建:假设你当前不在主目录下,但在 /var/www 下创建一个名为 MyProject 的目录。

touch命令

1
2
3
4
5
6
7
8
1:基本使用:在当前目录下创建一个名为 newfile.txt 的新文件。

2:创建多个文件:在同一命令中创建多个文件,如 file1.txt, file2.txt, 和 file3.txt。

3:更新文件时间戳:假设你有一个文件 oldfile.txt,使用 touch 更新其访问和修改时间戳。

4:使用绝对路径创建文件:在 /var/log 目录下创建一个名为 log.txt 的文件。

rm命令

1
2
3
4
5
6
7
8
1:基本删除:删除当前目录下的一个名为 example.txt 的文件。

2:删除多个文件:删除当前目录下的多个文件,例如 file1.txt, file2.txt, 和 file3.txt。

3:递归删除目录:删除一个名为 mydir 的目录及其内容。

4:强制删除:使用 -f 选项强制删除一个名为 lockedfile.txt 的文件。

【实操】项目环境搭建

学习目标

掌握聊天机器人相关虚拟机配置,完成项目环境搭建

导入虚拟机

​ 为便于后续的知识学习,本项目的开发环境部署到了CentOS7系统,因此我们先安装一下开发环境。

​ 为了大家统一开发环境,我们在资料中提供了一套系统镜像,大家使用VMware软件来挂载即可快速启动。

挂载虚拟机

​ 解压《ai_node1.zip》文件,解压后,进入解压的虚拟机镜像文件夹,双击ai_node1.vmx即可挂载到你的虚拟机中(需提前安装虚拟机)。

FinalShell客户端链接

详见 AI环境_虚拟机搭建.md 文档, 如有任何问题, 请随时联系老师哟!

小结

Q1:聊天机器人项目虚拟机部署分为几步?

  • 1:解压《ai_node1》虚拟机压缩文件
  • 2:导入ai_node1.vmx文件到VMware软件中
  • 3:修改虚拟机网络设置

Python编程_基础语法与条件判断

大纲介绍

  • Python环境搭建

  • Python基础语法与变量

  • Python判断结构之if结构

【了解】Python概述与安装

学习目标

了解Python语言特点

掌握Python环境搭建与基础语法

为什么要学习Python

① 技术趋势

Python自带明星属性,热度稳居编程语言界前三

image-20210306090039676

https://www.tiobe.com/tiobe-index/

https://pypl.github.io/PYPL.html

② 简单易学

开发代码少,精确表达需求逻辑;==33个关键字,7种基本数据类型==;语法规则简单,接近自然语言。

image-20210306090337310

③ 应用广泛

Python语言涉及IT行业70%以上的技术领域

image-20210306090727147

Python语言的诞生

1989年,为了打发圣诞节假期,龟叔(吉多·范·罗苏姆)开始写Python语言的编译器 ;
1991年,第一个Python编译器诞生
Python这个名字,来自龟叔所挚爱的电视剧Monty Python’s Flying Circus (蒙蒂·蟒蛇的飞行马戏团)

image-20220223001443177

Python语言的优缺点

优点

简单:Python是一种代表简单主义思想的语言。阅读一个良好的Python程序就感觉像是在读英语一样,Python的这种代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身。

易学:就如同你即将看到的一样,Python极其容易上手。前面已经提到了,Python有极其简单的语法。

免费、开源:Python开源的。简单地说,你可以自由地阅读它的源代码、对它做改动、这是为什么Python如此优秀的原因之一,它是由一群希望看到一个更加优秀的Python的人创造并经常改进着的。

可移植性:由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就可以在下述任何平台上面运行。

丰富的库:Python标准库确实很庞大。它可以帮助你处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。记住,只要安装了Python,所有这些功能都是可用的。这被称作Python的“功能齐全”理念。

缺点

Python语言非常完善,没有明显的短板和缺点,唯一的缺点就是执行效率慢,这个是解释型语言所通有的,同时这个缺点也将被计算机越来越强大的性能所弥补。

Python版本的选择

Python3.x

​ Python3.6、==Python3.7==、Python3.8、Python3.9…

在生产环境中,我们⼀般不会选择最新版本的Python,因为可能会存在未知Bug,所以⼀般强烈建议大家在选择软件版本时,向前推1 ~ 2个版本。所以咱们课程主要讲解Python3.12版本。

Python解析器的作用

demo.py

1
print('Hello World')

由于Python属于高级语言,其并不能直接在计算机中运行,因为缺少Python语言的运行环境:Python解析器

image-20210306092814499

Python解析器的作用:==就是把Python代码转换为计算机底层可以识别的机器语言==,如0101…

Python解析器的种类

==① CPython,C语言开发的解释器[官方],应⽤广泛的解释器。==

② IPython,基于CPython的一种交互式解释器。

③ 其他解释器

PyPy,基于Python语言开发的解释器。

JPython,运⾏在Java平台的解释器,直接把Python代码编译成Java字节码执⾏。

IronPython,运⾏在微软.Net平台上的Python解释器,可直接把Python代码编译成.Net的字节码。

下载Python解析器

下载地址:https://www.python.org/downloads/release/python-379/

[单击上述链接] – 查找目标文件:Windows x86-64 executable installer – 单击即可下载。

Anaconda安装Python解析器

简介

Anaconda 是一个开源的 Python 和 R 语言发行版,专注于简化数据科学、机器学习和科学计算的开发环境管理,旨在为用户提供一套“开箱即用”的工具和库,帮助快速搭建科学计算所需的开发环境。

1741565552820

安装

1740668600059

1740668629646

1740668667912

1740668753327

1740668982175

1740670257930

1740670281760

1740670324881

测试

  • 打开开始菜单点击Anaconda Powershell Prompt, 分别输入 conda -Vpython -V, 能出现版本号, 即为安装成功.

  • 1740670596381

    1740670645915

小结

Q1:计算机中软件和硬件区别是什么 ?

  • 看得见,摸不着
  • 看得见,摸得着

Q2:Python语言的优点是什么 ?

  • 简单、易学、免费开源、可移植性好、具有丰富的系统库

【实操】Python开发利器之PyCharm

学习目标

完成PyCharm软件安装

实现PyCharm软件与Anaconda整合

为什么要安装PyCharm

工欲善其事必先利其器

在Python的开发领域,其开发工具非常非常多,EditPlus、Notepad++、Sublime Text3、Visual Studio Code、PyCharm(目前功能强大的IDE )

image-20210306102520443

PyCharm的主要作用

PyCharm是⼀种Python IDE (集成开发环境),带有一整套可以帮助用户在使用Python语言开发时提高其效率的⼯具,内部集成的功能如下:

Project管理

智能提示

语法高亮

代码跳转

调试代码

解释代码(解释器)

框架和库

……

PyCharm的分类

PyCharm一共有两个版本:专业版(收费) 与 社区版(免费、开源)

image-20210306102803654

在基础班,PyCharm社区版足够我们使用,绰绰有余。

下载PyCharm

下载地址:https://www.jetbrains.com/pycharm/download/#section=windows

image-20210306103210207

PyCharm安装

第一步:双击PyCharm软件安装包,进行软件安装

image-20210306104505660

第二步:设置软件的安装路径,理论上没有任何要求,但是建议放在除C盘以外的盘符

image-20210306105046370

第三步:PyCharm基本设置,创建桌面图标与.py文件关联

image-20210306105223088

【!!!!千万别汉化】

PyCharm软件的使用(更改)

☆ 创建Python项目

什么是项目?其实我们在实际开发中,每次参与一个工作的开发都是一个项目的开发过程。所以使用PyCharm的第一件事就是学习Python项目的创建过程。

第一步:创建项目

1740669584662

第二步:设置项目路径,必须放在C盘以外的盘符(非常重要!!!)

1740671399407

配置完成后,单机Create创建Python项目。

☆ 新建文件与代码书写

1740671502874

编写Hello World

1
print('Hello World')

☆ 运行代码

1740671569004

运行结果:

1740671588897

☆ 设置或更换Python解析器

打开File文件,找到Settings设置,如下图所示:更换Python解析器

1740671620828

☆ PyCharm软件本身设置

① 软件主题(软件未来的样式)

② 编码字体的设置

③ 代码字号的设置(文字大小)

打开File文件 => Settings设置,找到界面设置:

image-20210306115108007

主题设置:

image-20210306115322452

字体与字号设置:

image-20210306115516870

字体设置:

image-20210306115611339

字号设置:

image-20210306115735435

☆ 打开项目与关闭项目

打开项目:本身项目已经存在了,我们直接打开。

image-20210306120615122

选择项目目录(文件夹)即可,如下图所示:

image-20210306120712306

① This Window => 覆盖当前项⽬,从⽽打开目标项目

② New Window => 在新窗⼝打开,则打开两次PyCharm,每个PyCharm负责一个项⽬

③ Attach => 把两个项目合并在一起,放在同一个窗口中

关闭项目:对已经运行项目进行关闭操作。

image-20210306120425927

【熟悉】Python注释与快捷键

学习目标

了解Python注释作用

掌握常见的注释格式

熟练使用常见的快捷键

注释的作用

首先强调一件事:Python代码 => Python解析器 => 机器语言,但是注释经过了Python的解释器并不会解析与执行。因为其主要就是进行代码的注释。

注释作用:==提高代码的阅读性==

image-20210306143714495

在我们编写Python程序时,为了了提高程序的可读性,强烈建议大家为核心代码添加注释信息。

Python注释的基本语法

☆ 单行注释

单行注释,以”#”(Shift + 3)号开头,只能注释一行内容

1
# 注释内容

示例代码:

第一种:代码行的上面

1
2
# 输出Hello World字符串
print('Hello World')

第二种:放在代码的后面(代码后面保留2个空格)

1
print('Hello World')  # 输出Hello World字符串

☆ 多行注释

多行注释:可以同时注释多行代码或程序,常用于代码块的注释

基本语法:

1
2
3
4
5
6
"""
注释内容
第一行
第二行
第三行
"""

1
2
3
4
5
6
'''
注释内容
第一行
第二行
第三行
'''

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"""
Hi, 大家好
我是黑马程序员的小伙伴
从今天开始,我们将一起学习Python这门语言
"""

'''
Hi, 大家好
我是黑马程序员的小伙伴
从今天开始,我们将一起学习Python这门语言
'''
print('Hi, 大家好')
print('我是黑马程序员的小伙伴')
print('从今天开始,我们将一起学习Python这门语言')

☆ PyCharm注释小技巧(快捷键)

在PyCharm中,我们可以使用Ctrl + /斜杠来对代码或程序进行快速注释。

代码提示

在PyCharm中,当我们输入Python关键字中的前2~3个字符,其会自动进行代码提示。这个时候,我们只需要按回车即可以快速的输入某个内容。

image-20210306150352389

代码保存

编写代码时,一定要养成一个好的习惯,使用Ctrl + S快速对代码进行保存操作。

个人建议,当写完一行代码时,就按一次。

撤销与恢复

如果不小心删除了某行代码,这个时候我们可以快速按Ctrl + Z就可以快速进行恢复。每按一次就撤销一次,如果撤销多了,怎么办?

答:还可以通过Ctrl + Y进行恢复操作

学习目标

Q1:为什么要给程序写注释?

  • 提高代码的阅读性

Q2:Python中注释有几种常见格式,特点是什么

  • 单行注释,以”#”号开头,只能注释一行内容
  • 多行注释:可以同时注释多行代码或程序,常用于代码块的注释

【掌握】Python中的变量

学习目标

理解变量的定义与使用

熟悉变量的命名规则和数据类型

引入变量的概念

那什么是变量呢?

==① 变量是存储数据的容器==

==② 变量在程序运行过程中是可以发生改变的量==

==③ 变量存储的数据是临时的==

变量的定义

基本语法:

1
2
变量名称 = 变量的值
注:等号的两边都要保留一个空格,其实Python中建议符号的两边尽量都要保留一个空格

说明:在Python程序中,这个等号和日常生活中的等号不太一样,其有一个专业名词:赋值运算符,其读法:要从右向左读,把变量的值通过 = 赋值给左边的变量。

变量的命名规则

标识符命名规则是Python中定义变量名称时一种命名规范,具体如下:

==① 由数字、字母、下划线(_)组成==

==② 不能数字开头==

==③ 严格区分⼤小写==

==④ 不能使⽤内置关键字作为变量名称==

image-20210306155908564

举个栗子:

① abc、abc123、_abc、hello(合理)

② 123abc、@abc、abc-123(不合理)

③ _(下划线) => 请问这可以是一个变量名称么?答:可以

1
2
for _ in range(10):
...

注意:在Python变量命名时,不建议使用_开头,因为其与后面要学习的私有属性想冲突

④ 变量abc和变量ABC是同一个变量么?答:不一样,这是两个完全不同的变量

⑤ 记不住Python关键字怎么办?答:借助于help()方法

1
>>> help('keywords')

推荐变量的命名规则

① 变量命名一定要做到见名知义。

② 大驼峰:即每个单词首字母都大写,例如: MyName 。

③ 小驼峰:第二个(含)以后的单词首字母大写,例如: myName 。

④ 下划线:例如: my_name 。

变量的定义与调用

在Python中,记住:变量一定要先定义,后使用,否则会报错。

定义:

1
2
name = 'itheima'
address = '北京市顺义区京顺路99号'

调用:

1
2
3
4
print(name)
print(address)

print(name, address)

变量的定义与使用常见问题

① 变量与字符串如何区别:

==在Python中,如果要赋值的内容添加了单引号或者双引号,其就是Python中的一种数据类型:叫做字符串(日常生活中的文本信息)==

② print打印变量时,喜欢为其添加引号

1
2
3
print(name)  # 输出变量name对应的值

print('name') # 输出'name'这个字符串

③ PyCharm快捷键 => Ctrl + Alt + L => 代码格式化

变量的数据类型

变量的定义非常的简单,但是很多小伙伴可能会想:变量除了存储这种字符类型的数据以外,还能存储其他类型的数据么?其实,在 Python中,我们为了应对不同的业务需求,也会把数据分为不同的类型,如下图所示:

image-20210306162601034

面试题:请手写出Python中的7种数据类型?

答:数值类型、布尔类型、字符串类型、列表类型、元组类型、集合类型、字典类型

今天我们只需要了解前3种即可。

问题:如何判断一个变量到底是什么类型?

答:① 使用type(变量名称)方法,返回变量的数据类型 ② isinstance(变量名称,数据类型),只能返回True或False(真的还是假的)

数值类型

数值类型就是我们日常生活中的数字,数字又分为两种形式:整数 与 小数(带小数点)

整数类型:int类型

小数类型:float类型

案例1:定义一个人的信息,姓名:Tom、年龄18岁

1
2
3
name = 'Tom'
age = 18
print(type(age))

案例2:定义一个超市收银系统,写入一个名称:大白菜,价格:3.5

1
2
3
name = '大白菜'
price = 3.5
print(type(price))

布尔类型

布尔类型是与逻辑相关一种数据类型,只有两个值:True(真)与False(假)

案例1:手工定义一个flag变量,其值为True

1
2
3
flag = True
print(flag)
print(type(flag))

字符串类型

在Python变量定义中,如果其赋值的内容是通过单引号或双引号引起来的内容就是字符串str类型。

1
2
msg = '这家伙很懒,什么都没有留下...'
print(type(msg))

其他类型(了解)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1、list列表类型
list1 = [10, 20, 30, 40]
print(type(list1))

# 2、tuple元组类型
tuple1 = (10, 20, 30, 40)
print(type(tuple1))

# 3、set集合类型:去重
set1 = {10, 20, 30}
print(type(set1))

# 4、dict字典类型:查询、搜索
dict1 = {'name':'itheima', 'age':18}
print(type(dict1))

小结

Q1:Python变量命名规则是什么?

  • 由数字、字母、下划线(_)组成
  • 不能数字开头
  • 严格区分⼤小写
  • 使⽤内置关键字作为变量名称

Q2:Python变量有哪些数据类型?

  • 数值型、布尔型、字符串、列表、元组、集合、字典

【掌握】Python的输入与输出

学习目标

掌握Python中的格式化输出方法,百分号格式化、format方法和f格式化

理解转义字符的使用

掌握Python中的输入方法,理解input()函数的使用及其返回值的类型

格式化输出

目前为止,我们所有的输出都是直接通过print(变量名称)形式直接打印的。但是实际工作中,我们可能需要对变量的输出进行格式化操作(==按照一定格式进行输出==)。

(张三,20,北京昌平

变量的格式化

百分号格式化输出

基本语法:

1
2
3
4
...
print(变量名称)
print('字符串%格式' % (变量名称))
print('字符串%格式 %格式 %格式' % (变量名称1, 变量名称2, 变量名称3))

%格式常见形式如下:

格式符号 转换
==%s== 字符串
==%d== 有符号的十进制整数
==%f== 浮点数
%c 字符
%u 无符号十进制整数
%o 八进制整数
%x 十六进制整数(小写ox)
%X 十六进制整数(大写OX)
%e 科学计数法(小写’e’)
%E 科学计数法(大写’E’)
%g %f和%e的简写
%G %f和%E的简写

案例:定义两个变量name=’itheima’, age=18,按照如下格式进行输出:我的名字是itheima,今年18岁了。

image-20210306175326815

案例:定义两个变量title=’大白菜’,price=3.5,按照如下格式进行输出:今天蔬菜特价了,大白菜只要3.5元/斤。

1
2
3
4
title = '大白菜'
price = 3.5
# 格式化输出“今天蔬菜特价了,大白菜只要3.5元/斤。"
print("今天蔬菜特价了,%s只要%.2f元/斤。" % (title, price))

其实除了%f可以设置小数点位数以外,%d也可以填充序号。

案例:定义两个变量id=1,name=’itheima’,按照如下格式进行输出:姓名itheima,学号000001

1
2
3
id = 1
name = 'itheima'
print("姓名%s,学号%06d" % (name, id))

format方法格式化输出

基本语法:

1
2
3
...
print('字符串{}'.format(变量名称1))
print('{}字符串{}'.format(变量名称1, 变量名称2))

案例:定义两个变量,name=’孙悟空’,mobile=’18878569090’,按照以下格式进行输出”姓名:孙悟空,联系方式:18878569090”

1
2
3
name = '孙悟空'
mobile = '18878569090'
print("姓名:{},联系方式:{}".format(name, mobile))

format方法简写形式格式化输出(推荐)

在Python3.6以后版本,为了简化format输出操作,引入了一个简写形式:

1
2
3
name = '孙悟空'
mobile = '18878569090'
print(f'姓名:{name},联系方式:{mobile}')

格式化输出中的转义符号

在字符串中,如果出现了\t和\n,其代表的含义就是两个转义字符

1
2
\t :制表符,一个tab键(4个空格)的距离
\n :换行符

案例:

1
2
print('*\t*\t*')
print('hello\nworld')

特别说明:==默认情况下,每个print()方法执行完毕后,都会输出一个\n换行符。如果不想让print()方法换行,可以添加一个end参数==

1
print('*', end='')

为什么需要输入

到目前为止,我们所有的程序都只能把数据输出给用户。但是实际工作中,我们经常输入获取用户的输入信息,如银行系统中的密码输入、淘宝中的用户登录验证。

image-20210306182224429

input()输入方法

在Python中,如果想让Python程序接受用户的输入信息,可以使用input()方法

基本语法:

1
input()

但是往往只有input()方法,其意义不大,我们还应该使用一个变量来临时接受用户的输入,已方便后期的操作。

1
变量名称 = input('提示信息:')

案例:银行系统中的,输入密码的过程

1
2
password = input('请输入您的银行卡密码:')
print(f'您输入的银行卡密码为:{password}')

input()方法重要事项

记住:所有由input()方法获取的数据都是==“字符串”==类型

1
2
3
4
5
name = input('请输入您的姓名:')
age = input('请输入您的年龄:')

print(type(name)) # <class 'str'>
print(type(age)) # <class 'str'>

总结:

① input()可以用于接收由外部设备输入的信息,但是如果用户没有输入任何内容,则input()函数会中止当前代码的继续执行,处于等待状态,直到用户输入结束。

② 所有由input()方法获取的数据都是==“字符串”==类型

小结

Q1:Python有几种格式化输出方式?

  • 百分比格式化
  • format格式化
  • f格式化

Q2:input方式输入特点是什么?

  • 用户不输入任何内容,input函数会中止代码继续执行
  • input函数获取的数据都是字符串类型

【掌握】Python数据类型转换

学习目标

掌握常见的Python数据类型转换

使用Python实现超市的收银系统

image-20210307095839494

Python:

1
2
3
4
5
name = input('请输入您要购买商品名称:')
id = input('请输入您要购买商品编号:')
price = input('请输入您要购买的商品价格:')

print(f'您购买了{name},商品编号为{id},商品价格为{price},欢迎下次光临!')

以上程序虽然可以按照上图完成程序的正常输出,但是遗留了一个非常严重的问题:这个价格price变量无法参与数学运算(如买了两个奥利奥,应该是18.5 * 2),原因在于input()方法返回的所有的结果都是str字符串类型。

怎么解决以上问题呢? 答:使用==数据类型转换==

了解Python数据类型的转换方法

函数 说明
==int(x)== 将x转换为一个整数
==float(x)== 将x转换为一个浮点数
complex(real [,imag ]) 创建一个复数,real为实部,imag为虚部
==str(x)== 将对象 x 转换为字符串
repr(x) 将对象 x 转换为表达式字符串
==eval(str)== 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s) 将序列 s 转换为一个元组
list(s) 将序列 s 转换为一个列表
chr(x) 将一个整数转换为一个Unicode字符
ord(x) 将一个字符转换为它的ASCII整数值
hex(x) 将一个整数转换为一个十六进制字符串
oct(x) 将一个整数转换为一个八进制字符串
bin(x) 将一个整数转换为一个二进制字符串

案例1:把用户输入的幸运数字,转换为整型

1
2
3
4
5
6
7
8
num = input('请输入您的幸运数字:')
print(type(num))

# 数据类型转换,把str字符串类型转换为int类型
print('-' * 20)

num = int(num)
print(type(num))

以上代码还可以简写为:

1
2
num = int(input('请输入您的幸运数字:'))
print(type(num))

案例2:多种数据类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1、整型转浮点类型 int => float
num1 = 10
print(float(num1))
print(type(float(num1)))

print('-' * 20)

# 2、浮点类型转换为整型 float => int,浮点转整型,其小数点后的数据会丢失!!!
num2 = 18.88
print(int(num2))

print('-' * 20)

# 3、把字符串类型转换为整型或浮点类型
str1 = '20'
str2 = '10.88'
print(type(int(str1)))
print(type(float(str2)))

案例3:eval()方法的使用,把字符串中的数字转换为原数据类型

1
2
3
price = input('请输入您购买商品的价格:')
print(eval(price))
print(type(eval(price)))

str1 = ‘10’ 经过eval(str1) 转换为int类型

str2 = ‘10.88’ 经过eval(str1) 转换为float类型

总结

Q1:Python数据类型转换方法一共学了几种方式?

  • int() :转整型

  • float() :转浮点类型

  • str() :转字符串类型

  • eval() :把字符串转换为原数据类型

    记住:① 如果一个字符串 * 数字,代表对这个字符串进行复制操作

    1
    2
    ② 当float浮点类型转换为int整型时,其小数点后面的数据会丢失,一定要记住这个特性。
    ③ 字符串转数值类型,字符串中的数据必须是有意义的数值

【掌握】Python运算符

学习目标

掌握Python算术运算符

熟练使用逻辑运算符与赋值运算符

了解短路运算符

运算入门案例

image-20210307110021473

需求:用户手工输入梯形的上底、下底以及高,能直接通过Python打印出梯形的面积为多少。

算术运算符

所谓的算数运算符就是我们日常生活中的加减乘除等待。

运算符 描述 实例
+ 1 + 1 输出结果为 2
- 1 - 1 输出结果为 0
* 2 * 2 输出结果为 4
/ 10 / 2 输出结果为 5
// 整除 9 // 4 输出结果为 2
% 取余(取模) 9 % 4 输出结果为 1
** 幂指数 2 ** 4 输出结果为 16,即2的4次方,2 * 2 * 2 * 2
() 小括号 小括号用来提高运算优先级,即 (1 + 2) * 3 输出结果为 9

案例1:了解一下算术运算符

1
2
3
4
5
6
7
8
num1 = 10
num2 = 2

# 四则运算 + - * /
print(f'加:{num1 + num2}')
print(f'减:{num1 - num2}')
print(f'乘:{num1 * num2}')
print(f'除:{num1 / num2}')

案例2:和其他编程语言不太相同的几个算术运算符

1
2
3
4
5
6
7
8
9
10
11
12
num1 = 20
num2 = 6
num3 = 5

# 1、整除
print(f'整除:{num1 // num2}')
# 2、求余数
print(f'余数:{num1 % num2}')
# 3、幂指数
print(f'幂指数:{num2 ** 3}')
# 4、圆括号
print(f'优先级:{(num1 + num2) * num3}')

算术运算符案例:求梯形的面积

知识点:用户输入、数据类型转换以及算术运算符

1
2
3
4
5
6
7
a = float(input('请输入上底:'))
b = float(input('请输入下底:'))
h = float(input('请输入高:'))

s = (a + b) * h / 2

print(f'梯形的面积:{s}')

赋值运算符

运算符 描述 实例
= 赋值 将=右侧的结果赋值给等号左侧的变量

变量名 = 变量值

== 等于号

案例1:把某个值赋值给某个变量

1
num = 10

案例2:多个变量同时进行赋值操作

1
2
3
n = 5
f = 10.88
s = 'hello world'

简写为:

1
2
3
4
n, f, s = 5, 10.88, 'hello world'
print(n)
print(f)
print(s)

案例3:多个变量赋予相同的值

1
2
a = 10
b = 10

简写为:

1
a = b = 10

复合赋值运算符

复合赋值运算符 = 算术运算符 结合 赋值运算符

image-20210307115314520

复合赋值运算符的计算顺序 = 先执行算术运算符,执行完毕后,把结果在赋值给左边的变量。

案例:AA制餐厅

需求: 假设你是一位很棒的AA制餐厅的服务员,你的任务是计算每位顾客的应付金额。
输入顾客人数,并赋值给total_friends变量。
输入总账单数值,并赋值配给 total_bill 变量。
在账单费用上加上20%的税,并计算最终账单总额均摊给顾客金额,然后打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
需求分析:
#第一步:获取用户输入顾客人数
#第二步:输入总账单数值
#第三步:计算加上20%税后的总账单
#第四步:计算每位顾客的应付金额
#第五步:打印每位顾客的应付金额



# 1.输入顾客人数
total_friends = int(input("请输入顾客人数: "))

# 2.输入总账单数值
total_bill = float(input("请输入总账单数值: "))

# 3.计算加上20%税后的总账单
total_bill_with_tax = total_bill * 1.20

# 4.计算每位顾客的应付金额
amount_per_person = total_bill_with_tax / total_friends

# 5.打印每位顾客的应付金额
print(f"每位顾客的应付金额是: {amount_per_person:.2f}元")

练习:均分巧克力

需求: 编写一个程序:将N个巧克力均分给M个儿童。
​ 从输入获取一个整数:巧克力数量,并将其分配给 chocolates 变量。
​ 从输入获取一个整数:孩子数量,并将其分配给 children 变量。
​ 计算每个孩子在除法后得到的巧克力数量并打印出来。
​ 计算剩余巧克力的数量并打印出来。
​ 假设:巧克力的数量总是大于孩子的数量。

1
2
3
4
5
6
7
需求分析:
# 1. 从输入获取一个整数:巧克力数量,并将其分配给
# 2. 从输入获取一个整数:孩子数量,并将其分配给 children 变量
# 3. 计算每个孩子在除法后得到的巧克力数量
# 4. 计算剩余巧克力的数量
# 5. 打印每个孩子得到的巧克力数量
# 6. 打印剩余巧克力的数量

比较运算符

image-20210307120855222

特别注意:当我们使用比较运算符对两个变量进行比较时,其返回一个布尔类型的值。

案例:两个数大小的比较

1
2
3
4
5
6
7
8
9
num1 = 10
num2 = 20

print(num1 > num2) # False
print(num1 < num2) # True
print(num1 >= num2) # False
print(num1 <= num2) # True
print(num1 == num2) # False
print(num1 != num2) # True

练习题

1
2
3
4
r = float(input('请输入要计算圆的半径:'))
PI = 3.14
s = PI * r ** 2
print(f'圆的面积为:{s}')

练习题2:赋值运算 => 输入身高,体重,求BMI = 体重(kg)/身高(m)的平方。

逻辑运算符

image-20210307144233542

not就是取反,只有一个表达式not 表达式,如果表达式为True,则not以后就返回False。反之,则返回True。

and :逻辑与,只有当两边的表达式全部为真,则最终结果返回为真,否则返回为假。

x :False

y :False

result = x and y

or :逻辑或,只要有一方为真,则整个表达式的返回结果就为真。除非两边的表达式都为假,则整个结果返回为假。

result = x or y

讲个非诚勿扰的小故事:

① 女孩子要求比较高,要求男孩子必须要有房且有车

1
2
3
4
5
6
7
8
表达式1 and 表达式2
当表达式1True且表达式2True时,则整个表达式返回结果为True
当表达式1或表达式2中有一个表达式为假,则整个表达式返回结果为False


有房 and 有车 则 牵手成功
有房 and 没车 则 牵手失败
没房 and 有车 则 牵手失败

② 女孩子要求一般,要求男孩子有房或者有车即可

1
2
3
4
5
6
7
8
9
表达式1 or 表达式2
当表达式1True或表达式2True时,则整个表达式返回结果为True
当表达式1与表达式2都为False时,则整个表达式才会返回False


有房 or 有车 则 牵手成功
有房 or 没车 则 牵手成功
没房 or 有车 则 牵手成功
没房 or 没车 则 牵手失败

逻辑与、或、非,其最终的返回结果也是一个布尔类型的值,True或False。另外在实际工作中,逻辑运算符也主要和if分支结构相结合。

案例:

1
2
3
4
5
6
7
8
a = 1
b = 2
c = 3

print((a > b) and (b > c)) # False
print((a > b) or (b > c)) # False
print((a < b) or (b > c)) # True
print(not (a > b)) # True

运算符_案例

案例需求

假设你是一位很棒的AA制餐厅的服务员,你的任务是计算每位顾客的应付金额。输入顾客人数,并赋值给total_friends变量。输入总账单数值,并赋值配给 total_bill 变量。在账单费用上加上20%的税,并计算最终账单总额均摊给顾客金额,然后打印。

实现思路

①输入顾客人数,输入总账单数值

②计算加上20%税后的总账单

③计算每位顾客的应付金额

④最后打印每位顾客的应付金额

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.输入顾客人数
total_friends = int(input("请输入顾客人数: "))

# 2.输入总账单数值
total_bill = float(input("请输入总账单数值: "))

# 3.计算加上20%税后的总账单
total_bill_with_tax = total_bill * 1.20

# 4.计算每位顾客的应付金额
amount_per_person = total_bill_with_tax / total_friends

# 5.打印每位顾客的应付金额
print(f"每位顾客的应付金额是: {amount_per_person:.2f}元")

巩固练习

需求: 编写一个程序:将N个巧克力均分给M个儿童。从输入获取一个整数:巧克力数量,并将其分配给 chocolates 变量。从输入获取一个整数:孩子数量,并将其分配给 children 变量。计算每个孩子在除法后得到的巧克力数量并打印出来。计算剩余巧克力的数量并打印出来。假设:巧克力的数量总是大于孩子的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 从输入获取一个整数:巧克力数量,并将其分配给 chocolates 变量
chocolates = int(input("请输入巧克力数量: "))

# 2. 从输入获取一个整数:孩子数量,并将其分配给 children 变量
children = int(input("请输入孩子数量: "))

# 3. 计算每个孩子在除法后得到的巧克力数量
chocolates_per_child = chocolates // children

# 4. 计算剩余巧克力的数量
remaining_chocolates = chocolates % children

# 5. 打印每个孩子得到的巧克力数量
print(f"每个孩子得到的巧克力数量是: {chocolates_per_child}")

# 6. 打印剩余巧克力的数量
print(f"剩余的巧克力数量是: {remaining_chocolates}")

总结

Q1:Python有几种逻辑运算符?特点是什么?

  • and 逻辑与,只有当两边的表达式全部为真,则最终结果返回为真,否则返回为假
  • or 逻辑或,只要有一方为真,则整个表达式的返回结果就为真。除非两边的表达式都为假,则整个结果返回为假。
  • not 就是取反,只有一个表达式not 表达式,如果表达式为True,则not以后就返回False。反之,则返回True。

【掌握】if选择判断结构

学习目标

掌握使用if条件判断语法,完成Python中条件判断相关需求

if选择判断结构作用

在日常开发中,只要有需要进行条件判断的语句基本上都是选择判断结构。

应用场景:

如果年龄大于等于18岁,则可以正常上网。

如果升级考试成绩大于60分,则可以顺利升级就业班。

if选择判断结构的基本语法

if基本语法:

1
2
3
4
if 条件判断:
则执行某段代码...

print()

案例代码:

1
2
3
4
5
6
if True:
print('条件成立执行的代码1')
print('条件成立执行的代码2')

# 下方的代码没有缩进到if语句块,所以和if条件无关
print('我是无论条件是否成立都要执行的代码')

if选择结构案例

需求:定义一个变量age = 18,判断这个变量是否大于等于18岁,如果满足条件,则可以上网。

案例1:直接定义判断,进行条件判断

1
2
3
age = 18
if age >= 18:
print('满足18岁要求,可以正常上网')

案例2:上网吧案例升级版

1
2
3
age = int(input('请输入您的年龄:'))
if age >= 18:
print('满足18岁要求,可以正常上网')

if选择原理图:学编程除了会写代码还不行,还要回画图(流程图)

image-20210307161204181

if…else…结构

基本语法:

1
2
3
4
if 条件判断:
当条件判断为True时,则执行这个语句段
else:
当条件判断为False时,则执行这个语句段

案例3:上网吧案例升级升级版,引入else

1
2
3
4
5
age = int(input('请输入您的年龄:'))
if age >= 18:
print('满足18岁要求,可以正常上网')
else:
print('不满足18岁要求,回家好好学习,天天向上')

if…else…结构原理图:

image-20210307162555060

if…elif…else多条件判断结构

如果条件1成立,则执行语句段1

如果条件2成立,则执行语句段2

当所有条件都不成立时,则执行else语句段中的内容

1
2
3
4
5
6
7
8
if 条件判断1:
如果此条件为True,则执行这个语句段
elif 条件判断2:
如果此条件为True,则执行这个语句段
elif ...:
...
else:
如果以上所有条件判断都不满足时,则执行这个语句段

if多重条件判断原理图:

image-20210307165907589

if_elif_else案例

案例需求

编写一个Python程序,根据用户输入的月份(1-12),判断该月份属于哪个季节(春季、夏季、秋季、冬季),并输出结果。如果用户输入的月份不在1-12范围内,程序应提示用户输入无效。

实现思路

①接受用户通过键盘输入任意一个合法月份

②使用if…elif 对用户输入月份进行判断

③匹配输出对应月份季节,如果匹配失败提示,无效月份

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.获取用户输入的月份
month = int(input("请输入月份 (1-12): "))

# 2.判断季节
if 3 <= month <= 5:
season = "春季"
elif 6 <= month <= 8:
season = "夏季"
elif 9 <= month <= 11:
season = "秋季"
elif month in [1, 2, 12]:
season = "冬季"
else:
season = "无效的月份"

# 3.输出季节
print(f"该月份属于: {season}")

巩固练习

需求: 编写一个程序,找出三个数字中最小的一个。取三个整数输入,并将它们存储在number1, number2, 和number2中。使用 “if…elif…else “语句打印它们之间最小的数字。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"""
需求: 编写一个程序:找出三个数字中最小的一个。
取三个整数输入,并将它们存储在number1, number2, 和number2中。
使用 "if...elif...else "语句打印它们之间最小的数字。
"""

# 1. 取三个整数输入,并将它们存储在number1, number2, 和number3中
number1 = int(input("请输入第一个数字: "))
number2 = int(input("请输入第二个数字: "))
number3 = int(input("请输入第三个数字: "))

# 2. 使用 "if...elif...else" 语句找出最小的数字
if number1 <= number2 and number1 <= number3:
# 3. 如果number1是最小的,打印number1
print(f"最小的数字是: {number1}")
elif number2 <= number1 and number2 <= number3:
# 4. 如果number2是最小的,打印number2
print(f"最小的数字是: {number2}")
else:
# 5. 如果number3是最小的,打印number3
print(f"最小的数字是: {number3}")

if嵌套结构(难点)

基本语法:

1
2
3
4
5
6
if 外层条件判断:
# 如果条件为True,则执行以下语句段
if 内层条件判断:
# 如果内层条件为True,则执行以下语句段
else:
# 如果条件为False,则执行以下语句段

嵌套结构看起来异常复杂,但是我们在编写时要遵循一个原则:==先编写外层判断,所有语句编写完成后,在编写内层条件判断结构。==

案例:法律规定,车辆驾驶员的血液酒精含量小于 20mg/100ml 不构成酒驾;酒精含量大于或等于 20mg/100ml 为酒驾;酒精含量大于或等于 80mg/100ml 为醉驾。编写 Python 程序判断是否为酒后驾车。

1
2
3
4
5
6
7
8
9
10
proof = int(input('请输入驾驶员100ml血液中的酒精含量:'))
# 判断proof酒精含量是否小于20mg
if proof < 20:
print('驾驶员不构成酒驾')
else:
# 已经构成酒驾 => 两种类型(酒驾与醉驾)
if proof >= 80:
print('驾驶员已构成醉驾')
else:
print('驾驶员已构成酒驾')

小结

Q1:Python有几种if结构

  • if..结构
  • if…else结构
  • if…elif..else结构

【实操】综合案例:石头剪刀布

需求分析

参与游戏的角色有两个(玩家 与 电脑),玩家手工出拳,电脑随机出拳,根据石头剪刀布判断输赢。

玩家:player(玩家手工输入石头0、剪刀1、布2)

电脑:computer(随机出拳)

输赢结果很重要,有三种情况:

① 玩家赢

☆ player:石头 赢 computer:剪刀

☆ player:剪刀 赢 computer:布

☆ player:布 赢 computer:石头

② 平局

只要player 与 computer出拳相等,就代表平局

③ 电脑赢

如果不满足以上两个条件,则电脑获胜!

未知知识点:如何让计算机随机出拳 => 随机

代码实现

确认:if…elif…else多条件分支结构

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一步:提示输入输入石头剪刀布,0-代表石头,1代表剪刀,2代表布
player = int(input('请输入您的出拳0-代表石头,1代表剪刀,2代表布:'))
# 第二步:电脑随机出拳(后续解决)
computer = 1
# 第三步:根据用户以及计算机的出拳判断输赢
# 什么情况,玩家会赢
# player==0且computer==1 或 palyer==1且computer==2 或 player==2且computer==0
if (player == 0 and computer == 1) or (player == 1 and computer == 2) or (player==2 and computer == 0):
print('玩家获胜')
elif player == computer:
print('平局')
else:
print('电脑获胜')

遗留问题:计算机没办法随机出拳

作业

作业一:根据考试成绩, 发放奖励

需求:根据考试成绩发放奖励,键盘录入小明的考试成绩并接收, 根据考试成绩发放奖励.

作业二:进阶版: 猜拳游戏

需求:上述猜拳案例无法实现计算机自动随机出拳。在原有的功能基础上,实现计算机随机出拳。增加游戏趣味性