Python编程 - 协程
前言
上篇文章主要讲述了python的进程,进程池和进程与线程对比等知识,接下来这篇文章再唠唠python的协程,让我们继续往下看!
一、协程的使用
python 中的协程是一种用于处理并发任务的高效工具,它依赖于 asyncio 库以及 async 和 await 关键字来实现异步编程。协程与传统的多线程或多进程并发模型不同,它通过事件循环实现任务的调度,在单线程内并发执行多个任务,适用于 I/O 密集型任务,如网络请求、文件操作等。
(一)基本使用
协程的定义使用 async 关键字,调用协程函数不会立即执行,而是返回一个协程对象,只有通过 await 关键字来执行它。await 会暂停当前协程的执行,等待另一个协程完成后再继续。
示例:
import asyncio# 定义一个协程函数
async def say_hello():print("Hello")await asyncio.sleep(1) # 模拟耗时操作print("World")# 定义主函数
async def main():await say_hello()# 启动事件循环
asyncio.run(main())
代码解释:
-
async def say_hello()定义了一个协程函数,它会在await asyncio.sleep(1)处暂停 1 秒,模拟一个耗时任务。 -
asyncio.run(main())启动了事件循环并执行协程。
(二)并发执行多个任务
协程的优势在于可以并发执行多个任务,避免顺序执行带来的阻塞。通过 asyncio.gather(),可以同时运行多个协程,从而提高程序效率。
示例:
import asyncioasync def task1():print("Task 1 started")await asyncio.sleep(2) # 模拟耗时操作print("Task 1 finished")async def task2():print("Task 2 started")await asyncio.sleep(1)print("Task 2 finished")async def main():# 并发运行两个任务await asyncio.gather(task1(), task2())asyncio.run(main())
代码解释:
-
asyncio.gather()用于并发执行task1()和task2()。两个任务同时开始,而不会等待前一个任务完成再执行下一个。
(三)协程与异步I/O
协程在处理 I/O 密集型任务时表现尤为出色,例如网络请求、文件读取等。通过 aiohttp 等异步库,可以大大提高程序的响应速度。
示例:
import asyncio
import timeasync def fetch_data(url):print(f"Fetching data from {url}")await asyncio.sleep(2) # 模拟网络请求print(f"Received data from {url}")async def main():start = time.time()# 并发执行多个网络请求await asyncio.gather(fetch_data('url1'), fetch_data('url2'), fetch_data('url3'))end = time.time()print(f"Total time: {end - start} seconds")asyncio.run(main())
代码解释:
-
asyncio.gather()并发运行多个网络请求的协程任务。 -
由于
await asyncio.sleep(2)是异步操作,因此多个请求会并发执行,从而显著减少总的执行时间。
(四)创建任务并独立执行
有时需要在不等待任务完成的情况下创建协程任务,可以使用 asyncio.create_task() 来创建一个独立执行的协程任务。
示例:
import asyncioasync def task1():print("Task 1 started")await asyncio.sleep(2)print("Task 1 finished")async def main():# 创建任务,但不等待其完成task = asyncio.create_task(task1())print("Task 1 is running in the background")await asyncio.sleep(1) # 主程序继续执行其他操作print("Main task completed")asyncio.run(main())
代码解释:
-
asyncio.create_task()创建了一个独立的协程任务,它会在后台执行,而主程序可以继续执行其他操作。 -
task1()的执行不会阻塞主任务的执行。
(五)协程中的异常处理
在协程中同样可以使用 try/except 进行异常处理,这样可以确保即使某个协程抛出异常,程序依然可以继续执行。
示例:
import asyncioasync def faulty_task():try:print("Faulty task started")await asyncio.sleep(1)raise ValueError("An error occurred!")except ValueError as e:print(f"Error caught: {e}")async def main():await faulty_task()asyncio.run(main())
该示例展示了如何在协程中捕获并处理异常,避免程序因异常崩溃。
(六)超时控制
有时,某些任务可能会长时间运行或卡住,可以通过 asyncio.wait_for() 为协程任务设置超时时间,如果任务未在指定时间内完成,将抛出 asyncio.TimeoutError 异常。
示例:
import asyncioasync def long_task():print("Long task started")await asyncio.sleep(5)print("Long task finished")async def main():try:# 设置超时时间为 3 秒await asyncio.wait_for(long_task(), timeout=3)except asyncio.TimeoutError:print("Task timed out!")asyncio.run(main())
asyncio.wait_for() 设置任务的超时时间。如果 long_task() 在 3 秒内未完成,将抛出 TimeoutError。
(七)总结
python 中的协程是一种高效处理并发任务的工具,特别适用于 I/O 密集型操作。通过 async/await 语法和 asyncio 库,可以在单线程环境下实现多任务并发,避免不必要的阻塞,极大提高程序的执行效率。
-
async和await是定义和调用协程的基础。 -
asyncio.gather()和asyncio.create_task()实现并发任务。 -
异常处理、超时控制、同步函数的异步化都可以在协程中灵活应用。
二、concurrent中的future对象
concurrent.futures 模块中,Future 对象是用于表示一个异步操作的结果,它可以帮助我们在多线程或多进程环境下跟踪任务的执行状态,并在任务完成后获取结果。Future 对象通常与线程池 ThreadPoolExecutor或进程池 ProcessPoolExecutor一起使用。
(一)概述
Future 对象是一个容器,用于存储异步任务的结果。它提供了多种方法和属性,用来检查任务的状态、获取任务的结果,或者等待任务完成。它的核心思想是:异步任务在后台执行,程序可以继续运行而不阻塞,而当我们需要结果时,可以通过 Future 对象访问该任务的执行状态和结果。
(二)使用场景
Future 对象一般与 concurrent.futures 模块中的线程池或进程池执行器executor一起使用,用来并发地执行多个任务。
ThreadPoolExecutor 示例
from concurrent.futures import ThreadPoolExecutordef task(n):print(f"处理任务 {n}")return n * 2# 使用线程池执行多个任务
with ThreadPoolExecutor(max_workers=3) as executor:futures = [executor.submit(task, i) for i in range(5)]for future in futures:print(f"任务结果: {future.result()}")
在上面的代码中,executor.submit() 提交任务并返回一个 Future 对象。通过调用 future.result(),我们可以获取任务的结果。如果任务还未完成,result() 将会阻塞直到任务完成。
(三)Future 对象的属性与方法
Future 对象提供了几种方法和属性,用来跟踪和获取异步任务的状态和结果。
主要方法和属性
-
future.result(timeout=None):用于获取异步任务的结果。如果任务完成,立即返回结果;如果任务尚未完成,则会等待。如果设置了timeout参数,则最多等待timeout秒,超过时间将抛出TimeoutError异常。如果任务在执行过程中抛出了异常,result()也会重新抛出该异常。 -
future.done():返回True表示任务已经完成(无论是成功完成还是抛出异常),否则返回False。 -
future.cancel():用于尝试取消异步任务。如果任务未开始执行,则可以取消并返回True;如果任务已经开始,则无法取消,返回False。 -
future.cancelled():返回True表示任务已经被取消,返回False表示任务没有被取消。 -
future.running():返回True表示任务正在执行,返回False表示任务未执行或已经完成。 -
future.add_done_callback(fn):给Future对象添加一个回调函数fn,当任务完成时会调用该函数。回调函数会接收Future对象作为参数。
示例:
from concurrent.futures import ThreadPoolExecutor
import timedef task(n):time.sleep(n)return n * 2with ThreadPoolExecutor() as executor:future = executor.submit(task, 3)print(f"任务完成了吗? {future.done()}")result = future.result() # 这里会阻塞直到任务完成print(f"任务结果:{result}")print(f"任务完成了吗? {future.done()}")
在这个例子中,future.done() 在任务开始执行时返回 False,而当任务完成后再调用 done() 则返回 True。
(四)Future 对象的回调机制
Future 对象支持回调机制,通过 add_done_callback() 方法,我们可以在任务完成时自动调用指定的回调函数。回调函数会接收当前 Future 对象作为参数。
示例:
from concurrent.futures import ThreadPoolExecutordef task(n):return n * 2def callback(future):print(f"回调:任务结果是 {future.result()}")with ThreadPoolExecutor() as executor:future = executor.submit(task, 3)future.add_done_callback(callback)
在这个示例中,当任务完成时,回调函数会自动被调用,并且可以通过传递的 Future 对象来获取任务结果。
(五)as_completed 和 wait
concurrent.futures 模块还提供了 as_completed() 和 wait() 函数,便于在多个 Future 对象上等待和检查结果。
-
as_completed(futures):返回一个迭代器,当每个Future对象完成时,它会按照完成的顺序返回。 -
wait(futures, timeout=None, return_when=ALL_COMPLETED):等待多个Future对象的完成,支持超时和条件返回。
示例:
from concurrent.futures import ThreadPoolExecutor, as_completeddef task(n):return n * 2with ThreadPoolExecutor() as executor:futures = [executor.submit(task, i) for i in range(5)]for future in as_completed(futures):print(f"任务结果: {future.result()}")
(六)总结
concurrent.futures 模块中的 Future 对象为我们提供了处理异步任务的方式。它可以通过线程池或进程池来并发执行任务,并允许我们轻松地获取任务的执行状态、结果以及异常处理。Future 对象的灵活性使它成为并发编程中不可或缺的工具,适用于 I/O 密集型任务、CPU 密集型任务等场景。
三、协程与线程和进程的交叉使用
在 Python 编程中,协程、线程和进程是三种常用的并发编程方式。它们各自适用于不同的场景,但在一些复杂的应用中,可能需要将它们交叉使用,以充分发挥它们各自的优势,实现更高效的并发处理。
(一)协程、线程和进程的区别
协程
-
轻量级并发:协程是由 Python 内部实现的用户级并发,基于事件循环。协程通过
async和await关键字实现异步非阻塞的 I/O 操作,适合处理 I/O 密集型任务,如网络请求、文件读写等。 -
单线程执行:协程通常在单个线程中执行,通过释放控制权 (
await) 来提高程序的并发性,不会占用多个 CPU 核心。
线程
-
操作系统级并发:线程由操作系统调度,可以在同一个进程内运行多个线程。线程可以利用多核 CPU 来并发执行代码。
-
多线程共享内存:线程共享进程的内存资源,但这也带来了线程安全问题,因此需要使用锁(Lock)或其他同步机制来避免数据竞争。
-
适合 I/O 密集型任务:对于 I/O 密集型任务,多线程可以有效提高程序的响应速度。
进程
-
独立的内存空间:进程是完全独立的运行实体,拥有自己的内存空间和资源。通过
multiprocessing模块可以在不同的 CPU 核心上并行运行进程。 -
进程间通信(IPC):进程间不能直接共享内存,因此需要使用管道、队列等方式进行通信。
-
适合 CPU 密集型任务:由于 Python 的全局解释器锁(GIL),在单个进程内无法同时运行多个 Python 字节码,但通过多进程可以避免 GIL 的影响,充分利用多核 CPU,适合 CPU 密集型任务如图像处理、大数据计算等。
(二)协/线/进程的交叉使用场景
- 协程与线程的交叉使用
协程可以在单线程中提供高效的 I/O 并发处理,但有时需要同时进行一些阻塞的同步操作,或者需要利用多核 CPU 进行并发计算时,可以将协程和线程结合使用。
示例:在协程中运行阻塞的同步代码
import asyncio
from concurrent.futures import ThreadPoolExecutor
import time# 阻塞的同步任务
def blocking_task():time.sleep(2)return "任务完成"# 使用协程调度异步任务
async def main():loop = asyncio.get_running_loop()with ThreadPoolExecutor() as pool:# 在线程池中运行同步阻塞任务result = await loop.run_in_executor(pool, blocking_task)print(result)# 启动事件循环
asyncio.run(main())
在这个例子中,blocking_task 是一个同步任务,通过 ThreadPoolExecutor 在单独的线程中运行,从而避免阻塞事件循环。协程通过 await 来异步等待线程中的任务完成,这种方式结合了协程的异步优势和线程的多核并发处理能力。
- 协程与进程的交叉使用
在某些情况下,单线程中的协程可能无法满足 CPU 密集型任务的需求,因此可以结合进程来处理耗费 CPU 的任务。
示例:在协程中并发运行多进程任务
import asyncio
from concurrent.futures import ProcessPoolExecutor
import time# CPU 密集型任务
def cpu_bound_task(n):total = 0for i in range(1000000 * n):total += ireturn total# 使用协程调度异步任务
async def main():loop = asyncio.get_running_loop()with ProcessPoolExecutor() as pool:# 在进程池中运行 CPU 密集型任务result = await loop.run_in_executor(pool, cpu_bound_task, 5)print(f"计算结果: {result}")# 启动事件循环
asyncio.run(main())
在这个例子中,cpu_bound_task 是一个 CPU 密集型任务,它在协程环境中通过 ProcessPoolExecutor 来并发执行。协程负责调度和等待进程的结果返回,从而避免事件循环被阻塞。
- 线程与进程的交叉使用
有时我们可能需要同时处理 I/O 密集型和 CPU 密集型任务,这时可以考虑将线程和进程结合使用。
示例:线程池和进程池的结合
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time# I/O 密集型任务
def io_task():time.sleep(1)print("I/O 密集型任务完成")# CPU 密集型任务
def cpu_task(n):total = 0for i in range(1000000 * n):total += iprint(f"CPU 密集型任务结果: {total}")# 使用线程池和进程池并发执行任务
def main():with ThreadPoolExecutor() as thread_pool, ProcessPoolExecutor() as process_pool:# 在线程池中运行 I/O 密集型任务for _ in range(3):thread_pool.submit(io_task)# 在进程池中运行 CPU 密集型任务for _ in range(2):process_pool.submit(cpu_task, 5)if __name__ == "__main__":main()
在这个示例中,io_task 在线程池中并发执行,而 cpu_task 则在进程池中运行。这种设计模式使得我们可以在同一个程序中同时处理 I/O 密集型任务和 CPU 密集型任务,从而最大化利用系统资源。
(三)总结
协程、线程和进程各有其优点和适用场景:
-
协程:适用于 I/O 密集型任务,尤其是大量网络请求、文件操作等场景,能够高效地进行异步非阻塞操作。
-
线程:适用于 I/O 密集型任务,可以在多核 CPU 上并发执行,但需要注意线程安全和锁的问题。
-
进程:适用于 CPU 密集型任务,能够充分利用多核 CPU,但进程间通信的开销较大。
四、总结
这篇文章主要讲的是协程的基本使用,原理,以及协程、线程和进程间的差别和交叉使用,根据不同的需求使用不同的功能,使得代码运行效率更高!
相关文章:
Python编程 - 协程
前言 上篇文章主要讲述了python的进程,进程池和进程与线程对比等知识,接下来这篇文章再唠唠python的协程,让我们继续往下看! 一、协程的使用 python 中的协程是一种用于处理并发任务的高效工具,它依赖于 asyncio 库以…...
如何在没有备份的情况下恢复 Mac 上丢失的数据
Mac 是您数字世界的中心。它上面可能保存着照片和视频等回忆,以及您不再联系的朋友和家人发来的旧电子邮件。您可能花了数小时导入整个 CD 收藏。您还可能保存着重要文档,例如演示文稿和工作文件、家庭账户或学校或大学的作业。 如果由于某种原因您丢失…...
SpringBoot:解析excel
解析Excel文件,可以使用Apache POI库 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version> </dependency> 上代码: /*** <b>Functio…...
Tomcat窗口运行修改窗口标题显示项目日期时间
1、修改配置文件catalina.bat文件 在Tomcat路径 bin文件夹下 set TITLETomcat.xxx.Server [%DATE% %TIME%] 显示:Tomcat.xxx,Server [2024/09.18 周三 12:01:30]...
8-----手机机型维修工具助手 功能较全 涵盖解锁 刷机 修复等选项 维修推荐
上图是一款功能较全的维修加密狗。目前可以无限制 任何人使用。看图片可以了解其中涵盖刷机 解锁 修复分区 查看短接图 安装驱动 修复基带等等选项。而且其中有针对各个机型型号的对应功能操作。以及一些rec5.0相关的操作选项。 通过此博文了解 ★★★★★此工具涵盖的一些…...
集群聊天服务器项目【C++】(四)cmake介绍和简单使用
我们上次用shell命令和vscode编译链接muduo库服务端代码,本章节实现编写CMakeLists.txt来编译项目。本次简单介绍CMake,并用Cmake编译上次的muduo服务器代码。 1.为什么使用cmake 我们在编译项目时,如果编写Makefile的话,常常会…...
Nginx+Tomcat(负载均衡、动静分离)
目录 一、Nginx概述 1.Nginx应用 二、正向代理和反向代理 1.正向代理 1.1主要作用 1.2工作原理 2.反向代理 2.1主要作用 2.2工作原理 三、负载均衡模式 1.轮询 2.最少连接数 3.IP 哈希 4.加权轮询 5.最少时间算法 6.一致性哈希 四、规划部署负载均衡和反向…...
前端分段式渲染较长文章
实现思路: 1. 后端返回整篇文章。 2. JavaScript 分段处理:将文章按一定的字符或段落长度分割,然后逐步将这些段落追加到页面上。 3. 定时器或递归调用:使用 setInterval 或 setTimeout 来控制段落的逐步渲染。 代码实现示例 …...
C#程序员的堕落从nuget开始:将自己的代码发布到nuget
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
【C/C++语言系列】malloc、calloc和realloc区别和用法
这三个函数都是在堆区分配内存的函数,头文件都是: #include<stdlib.h>下面分别介绍这三个函数: malloc: 函数原型: void *malloc(unsigned int num_bytes);功能:堆区开辟一段内存空间 num_nytes&…...
【Linux】POSIX信号量与、基于环形队列实现的生产者消费者模型
目录 一、POSIX信号量概述 信号量的基本概念 信号量在临界区的作用 与互斥锁的比较 信号量的原理 信号量的优势 二、信号量的操作 1、初始化信号量:sem_init 2、信号量申请(P操作):sem_wait 3、信号量的释放(…...
Spring Boot-消息队列相关问题
Spring Boot 消息队列相关问题及解决方案 消息队列(Message Queue, MQ)在分布式系统中的应用越来越广泛,尤其是在解耦系统、异步通信、负载均衡等场景中起到了至关重要的作用。消息队列为不同的服务提供了一种异步通信的机制,使得…...
[数据集][目标检测]岩石种类检测数据集VOC+YOLO格式4766张9类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):4766 标注数量(xml文件个数):4766 标注数量(txt文件个数):4766 标注…...
图像分割基本知识
计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割 图像分割 一、目标分割1.1 图像分割的定义1.2 任务类型1.2.1 任务描述1.2.2 任务类型 二、语义分割2.1 FCN网络2.1.1网络结构 2.2 Unet网络 三、UNet案例3.1 数据集获取3.1.1 设置相关信息3.1.2 图像…...
LIN总线CAPL函数——干扰LIN帧响应段(linInvertRespBit )
🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…...
【30天玩转python】网络编程基础
网络编程基础 网络编程是指编写能够在网络上进行通信的程序,通过网络进行数据的发送与接收。Python 提供了许多库和工具来进行网络编程,如 socket、urllib 和 requests。在这篇文章中,我们将介绍网络编程的基础知识,并演示如何使…...
【PCB工艺】如何实现PCB板层间的互连
系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 前言①、什么是通孔②、通孔是怎样产生的③、通孔种类④、盘中孔⑤、设计建议 前言 送给大学毕业后找不到奋斗方向的你…...
FastAPI--如何自定义Docs UI,包括多个APP、静态资源、元数据等
如何mount 一个FastAPI Application? “Mounting” means adding a completely “independent” application in a specific path, that then takes care of handling everything under that path, with the path operations declared in that sub-application. 示例代码 主…...
【FPGA XDMA AXI Bridge 模式】PCIe:BARs 和 AXI:BARs 含义解析
一. XDMA IP核两种模式 Xilinx的 DMA/Bridge Subsystem for PCI Express IP核中,支持普通的XDMA模式,但是这种模式只允许主机端发起PCIe 读写请求,FPGA内部无法主动发起读写请求,也即FPGA无法主动读写HOST的内存。 而该IP核的另…...
嵌入式-QT学习-小练习
1. 实现多窗口 2. 给按键增加图标 3. 动图展示 结果演示: Mul_Con main.cpp #include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }一、第一个窗口展示 …...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
