音视频入门基础:RTP专题(14)——FFmpeg源码中,对H.264的各种RTP有效载荷结构的解析
一、引言
由《音视频入门基础:RTP专题(10)——FFmpeg源码中,解析RTP header的实现》可以知道,FFmpeg源码的rtp_parse_packet_internal函数的前半部分实现了解析某个RTP packet的RTP header的功能。而在解析完RTP header后,rtp_parse_packet_internal函数内部会执行函数指针parse_packet指向的回调函数来对不同有效载荷类型的RTP payload进行解析:
static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,const uint8_t *buf, int len)
{
//...if (s->handler && s->handler->parse_packet) {rv = s->handler->parse_packet(s->ic, s->dynamic_protocol_context,s->st, pkt, ×tamp, buf, len, seq,flags);}
//...
}
比如,对于有效载荷类型为H.264的payload,parse_packet指向的回调函数为h264_handle_packet函数,此时通过h264_handle_packet函数对H.264格式的payload进行解析;对于有效载荷类型为AAC的payload,parse_packet指向的回调函数为aac_parse_packet函数,此时通过aac_parse_packet函数对AAC格式的payload进行解析。
二、h264_handle_packet函数的定义
h264_handle_packet函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavformat/rtpdec_h264.c:
// return 0 on packet, no more left, 1 on packet, 1 on partial packet
static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,AVStream *st, AVPacket *pkt, uint32_t *timestamp,const uint8_t *buf, int len, uint16_t seq,int flags)
{uint8_t nal;uint8_t type;int result = 0;if (!len) {av_log(ctx, AV_LOG_ERROR, "Empty H.264 RTP packet\n");return AVERROR_INVALIDDATA;}nal = buf[0];type = nal & 0x1f;/* Simplify the case (these are all the NAL types used internally by* the H.264 codec). */if (type >= 1 && type <= 23)type = 1;switch (type) {case 0: // undefined, but pass them throughcase 1:if ((result = av_new_packet(pkt, len + sizeof(start_sequence))) < 0)return result;memcpy(pkt->data, start_sequence, sizeof(start_sequence));memcpy(pkt->data + sizeof(start_sequence), buf, len);COUNT_NAL_TYPE(data, nal);break;case 24: // STAP-A (one packet, multiple nals)// consume the STAP-A NALbuf++;len--;result = ff_h264_handle_aggregated_packet(ctx, data, pkt, buf, len, 0,NAL_COUNTERS, NAL_MASK);break;case 25: // STAP-Bcase 26: // MTAP-16case 27: // MTAP-24case 29: // FU-Bavpriv_report_missing_feature(ctx, "RTP H.264 NAL unit type %d", type);result = AVERROR_PATCHWELCOME;break;case 28: // FU-A (fragmented nal)result = h264_handle_packet_fu_a(ctx, data, pkt, buf, len,NAL_COUNTERS, NAL_MASK);break;case 30: // undefinedcase 31: // undefineddefault:av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type);result = AVERROR_INVALIDDATA;break;}pkt->stream_index = st->index;return result;
}
该函数的作用是:对H.264格式的RTP payload(有效载荷)进行解析。H.264格式的RTP的payload有三种不同的有效载荷结构:Single NAL Unit Packet、Aggregation Packet(STAP-A、STAP-B、MTAP16、MTAP24)和Fragmentation Unit(FU-A、FU-B)。在h264_handle_packet函数中对这些有效载荷结构进行统一解析处理。
形参ctx:输入型参数。用来输出日志,可忽略。
形参data:输入型参数,指向一个PayloadContext(有效载荷上下文)变量。
形参st:输入型参数,指向一个AVStream类型变量。该变量存贮该路视频流的信息。
形参pkt:输出型参数。执行h264_handle_packet函数后,pkt会得到从该RTP packet的payload中得到的信息。
形参timestamp:输入型参数,其指向的变量的值为该RTP packet的RTP header中的timestamp(时间戳)。
形参buf:输入型参数,指针buf指向该RTP packet的RTP payload的第一个字节,即RTP payload header。
形参len:输入型参数,为该RTP packet的RTP payload的大小(以字节为单位)。
形参seq:输入型参数,为该RTP packet的RTP header中的sequence number(序列号)。
形参flags:输入型参数,表示该RTP packet的RTP header中的marker字段的值是否为1。
返回值:返回一个负数表示失败,FFmpeg不支持这种有效载荷结构;返回非负数表示成功。
三、h264_handle_packet函数的内部实现分析
(一)解析RTP payload header
h264_handle_packet函数内部,首先判断变量len(该RTP packet的RTP payload的大小)是否为0,如果为0,表示是空的H.264 RTP数据包,打印错误日志:“Empty H.264 RTP packet”:
uint8_t nal;uint8_t type;int result = 0;if (!len) {av_log(ctx, AV_LOG_ERROR, "Empty H.264 RTP packet\n");return AVERROR_INVALIDDATA;}
由《音视频入门基础:RTP专题(12)——RTP封装H.264时,RTP中的NAL Unit Type》可以知道,如果RTP payload为H.264格式,那RTP payload的第一个字节就是RTP payload header,RTP payload header的结构就是NALU Header(包含forbidden_zero_bit、nal_ref_idc、nal_unit_type)。h264_handle_packet函数内部通过下面语句将RTP payload header的nal_unit_type读取出来,赋值给变量type:
nal = buf[0];type = nal & 0x1f;/* Simplify the case (these are all the NAL types used internally by* the H.264 codec). */if (type >= 1 && type <= 23)type = 1;
然后h264_handle_packet函数中会根据不同的nal_unit_type值执行不同的逻辑来处理不同的有效载荷结构。
(二)解析Single NAL Unit Packet
当nal_unit_type范围在1至 23(含 23)之间时,有效载荷结构为Single NAL Unit Packet,此时该RTP packet的有效载荷中只包含一个NALU,h264_handle_packet函数中会执行下面代码块来处理Single NAL Unit Packet:
case 0: // undefined, but pass them throughcase 1:if ((result = av_new_packet(pkt, len + sizeof(start_sequence))) < 0)return result;memcpy(pkt->data, start_sequence, sizeof(start_sequence));memcpy(pkt->data + sizeof(start_sequence), buf, len);COUNT_NAL_TYPE(data, nal);break;
上面的代码块中,首先通过av_new_packet函数给pkt->data分配内存(关于av_new_packet函数用法可以参考:《FFmpeg源码:packet_alloc、av_new_packet、av_shrink_packet、av_grow_packet函数分析》),然后把该RTP packet的payload数据提取出来,加上值为“0001”(四字节)的起始码,存到pkt->data中:
数组start_sequence中存放的数据就是“0001”,表示H.264码流的NALU的起始码:
static const uint8_t start_sequence[] = { 0, 0, 0, 1 };
(三)解析STAP-A
当nal_unit_type值为24时,有效载荷结构为STAP-A,此时该RTP packet的有效载荷中可能包含多个NALU,h264_handle_packet函数中会执行下面代码块来处理STAP-A。
case 24: // STAP-A (one packet, multiple nals)// consume the STAP-A NALbuf++;len--;result = ff_h264_handle_aggregated_packet(ctx, data, pkt, buf, len, 0,NAL_COUNTERS, NAL_MASK);break;
上面的代码块中,首先会执行语句:“buf++;len--;”让指针buf指向RTP payload header之后的数据,让len的值等于该RTP packet的RTP payload去掉RTP payload header之后的大小(以字节为单位)。然后会执行ff_h264_handle_aggregated_packet函数处理STAP-A。
ff_h264_handle_aggregated_packet函数定义在libavformat/rtpdec_h264.c中:
int ff_h264_handle_aggregated_packet(AVFormatContext *ctx, PayloadContext *data, AVPacket *pkt,const uint8_t *buf, int len,int skip_between, int *nal_counters,int nal_mask)
{int pass = 0;int total_length = 0;uint8_t *dst = NULL;int ret;// first we are going to figure out the total sizefor (pass = 0; pass < 2; pass++) {const uint8_t *src = buf;int src_len = len;while (src_len > 2) {uint16_t nal_size = AV_RB16(src);// consume the length of the aggregatesrc += 2;src_len -= 2;if (nal_size <= src_len) {if (pass == 0) {// countingtotal_length += sizeof(start_sequence) + nal_size;} else {// copyingmemcpy(dst, start_sequence, sizeof(start_sequence));dst += sizeof(start_sequence);memcpy(dst, src, nal_size);if (nal_counters)nal_counters[(*src) & nal_mask]++;dst += nal_size;}} else {av_log(ctx, AV_LOG_ERROR,"nal size exceeds length: %d %d\n", nal_size, src_len);return AVERROR_INVALIDDATA;}// eat what we handledsrc += nal_size + skip_between;src_len -= nal_size + skip_between;}if (pass == 0) {/* now we know the total size of the packet (with the* start sequences added) */if ((ret = av_new_packet(pkt, total_length)) < 0)return ret;dst = pkt->data;}}return 0;
}
由《音视频入门基础:RTP专题(12)——RTP封装H.264时,视频的有效载荷结构》可以知道,
当有效载荷结构(即RTP layload)为STAP-A时,此时:
该RTP数据包(RTP packet) = RTP header + STAP-A
一个STAP-A = RTP payload header(此时为STAP-A NAL HDR) + 若干个single-time aggregation units
一个single-time aggregation units = NAL unit size(固定占2字节) + NAL unit(包含NALU Header)
ff_h264_handle_aggregated_packet函数中,首先会通过AV_RB16宏定义将single-time aggregation unit的NAL unit size读取出来,存入变量nal_size中。关于AV_RB16宏定义的用法可以参考:《FFmpeg源码:AV_RB32、AV_RB16、AV_RB8宏定义分析》
uint16_t nal_size = AV_RB16(src);
通过av_new_packet函数让指针dst(即pkt->data)指向一个分配的内存块:
if (pass == 0) {/* now we know the total size of the packet (with the* start sequences added) */if ((ret = av_new_packet(pkt, total_length)) < 0)return ret;dst = pkt->data;}
如果NAL unit size超过剩下的RTP payload的大小,表示出错了,打印错误日志:"nal size exceeds length: %d %d\n"。如果没超过,根据NAL unit size的值把该RTP packet的payload中的每个NALU提取出来,每个NALU前都加上值为“0001”(四字节)的起始码,存到dst(即pkt->data)中:
if (nal_size <= src_len) {if (pass == 0) {// countingtotal_length += sizeof(start_sequence) + nal_size;} else {// copyingmemcpy(dst, start_sequence, sizeof(start_sequence));dst += sizeof(start_sequence);memcpy(dst, src, nal_size);if (nal_counters)nal_counters[(*src) & nal_mask]++;dst += nal_size;}} else {av_log(ctx, AV_LOG_ERROR,"nal size exceeds length: %d %d\n", nal_size, src_len);return AVERROR_INVALIDDATA;}
执行ff_h264_handle_aggregated_packet函数后,pkt->data指向的缓冲区会得到该RTP packet的payload中的每个NALU的数据(可能包含多个NALU,每个NALU的数据之间以“0001”分隔)。
(四)解析FU-A
当nal_unit_type值为28时,有效载荷结构为FU-A,此时一个NALU可能会被分割成多个RTP Packet,h264_handle_packet函数中会执行下面代码块来处理FU-A:
case 28: // FU-A (fragmented nal)result = h264_handle_packet_fu_a(ctx, data, pkt, buf, len,NAL_COUNTERS, NAL_MASK);break;
h264_handle_packet_fu_a函数定义在libavformat/rtpdec_h264.c中:
static int h264_handle_packet_fu_a(AVFormatContext *ctx, PayloadContext *data, AVPacket *pkt,const uint8_t *buf, int len,int *nal_counters, int nal_mask)
{uint8_t fu_indicator, fu_header, start_bit, nal_type, nal;if (len < 3) {av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H.264 RTP packet\n");return AVERROR_INVALIDDATA;}fu_indicator = buf[0];fu_header = buf[1];start_bit = fu_header >> 7;nal_type = fu_header & 0x1f;nal = fu_indicator & 0xe0 | nal_type;// skip the fu_indicator and fu_headerbuf += 2;len -= 2;if (start_bit && nal_counters)nal_counters[nal_type & nal_mask]++;return ff_h264_handle_frag_packet(pkt, buf, len, start_bit, &nal, 1);
}
由《音视频入门基础:RTP专题(12)——RTP封装H.264时,视频的有效载荷结构》可以知道,FU-A 由一个8位的碎片单元指示符(FU indicator,又称FU identifier,其实就是RTP payload header)、一个8位组的碎片单元报头(FU header)和一个碎片单元有效载荷(FU payload,又称fragmentation unit payload,H264 NAL Unit Payload)组成。
h264_handle_packet_fu_a函数中,通过下面代码将FU indicator读取出来,存到变量fu_indicator中;将FU header读取出来,存到变量fu_header中;把fu_header的S位(起始位)读取出来,存到变量start_bit中;把fu_header的Type字段(表示NAL单元有效载荷类型)读取出来,存到变量nal_type中;变量nal相当于存贮该NALU的NALU Header:
fu_indicator = buf[0];fu_header = buf[1];start_bit = fu_header >> 7;nal_type = fu_header & 0x1f;nal = fu_indicator & 0xe0 | nal_type;
让指针buf指向FU indicator和FU header之后的数据,即指向FU-A的FU payload。让变量len的值变为该FU payload的大小(以字节为单位):
// skip the fu_indicator and fu_headerbuf += 2;len -= 2;
然后h264_handle_packet_fu_a函数中会调用ff_h264_handle_frag_packet函数处理该FU-A的FU payload:
return ff_h264_handle_frag_packet(pkt, buf, len, start_bit, &nal, 1);
ff_h264_handle_frag_packet函数定义在libavformat/rtpdec_h264.c中。可以看到,执行ff_h264_handle_frag_packet函数后,pkt->data会得到该FU-A的FU payload(前面加上“0001”的起始码)中的数据,即得到该NALU在该RTP Packet中的分片数据:
int ff_h264_handle_frag_packet(AVPacket *pkt, const uint8_t *buf, int len,int start_bit, const uint8_t *nal_header,int nal_header_len)
{int ret;int tot_len = len;int pos = 0;if (start_bit)tot_len += sizeof(start_sequence) + nal_header_len;if ((ret = av_new_packet(pkt, tot_len)) < 0)return ret;if (start_bit) {memcpy(pkt->data + pos, start_sequence, sizeof(start_sequence));pos += sizeof(start_sequence);memcpy(pkt->data + pos, nal_header, nal_header_len);pos += nal_header_len;}memcpy(pkt->data + pos, buf, len);return 0;
}
(五)解析其它有效载荷结构
当nal_unit_type值为25、26、27、29时,有效载荷结构分别为STAP-B、MTAP-16、MTAP-24、FU-B。由于FFmpeg目前(截止7.0.1版本)还不支持这几种有效载荷结构,所以h264_handle_packet函数中会通过avpriv_report_missing_feature函数打印错误日志:"RTP H.264 NAL unit type %d":
case 25: // STAP-Bcase 26: // MTAP-16case 27: // MTAP-24case 29: // FU-Bavpriv_report_missing_feature(ctx, "RTP H.264 NAL unit type %d", type);result = AVERROR_PATCHWELCOME;break;
四、总结
1.FFmpeg源码中,在h264_handle_packet函数内部统一对H.264的各种RTP有效载荷结构进行解析处理。
2.FFmpeg目前(截至7.0.1版本)还不支持STAP-B、MTAP-16、MTAP-24、FU-B这几种有效载荷结构的解析。所以如果要解析包含这几种有效载荷结构的RTP流,可能会出错。要想支持,可以修改FFmpeg源码,在h264_handle_packet函数内部添加解析对应的有效载荷结构的代码。
相关文章:
音视频入门基础:RTP专题(14)——FFmpeg源码中,对H.264的各种RTP有效载荷结构的解析
一、引言 由《音视频入门基础:RTP专题(10)——FFmpeg源码中,解析RTP header的实现》可以知道,FFmpeg源码的rtp_parse_packet_internal函数的前半部分实现了解析某个RTP packet的RTP header的功能。而在解析完RTP head…...
2. 电脑主机上配置机器人环境(具身智能机器人套件)
操作步骤跟树莓派一致 1. 安装 Miniconda curl -O https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-aarch64.sh bash ~/Anaconda3-2024.10-1-Linux-aarch64.sh source ~/.bashrc conda config --set auto_activate_base True source ~/.bashrc2. 配置LeRobot …...
IDEA2023 使用枚举类型java: 非法字符: ‘\ufffd‘
一、异常: 二、原因 文件编码问题 IDE或文本编辑器的文件编码设置不正确,可能会导致在保存文件时引入了错误的字符。 三、解决 在IntelliJ IDEA中,你可以通过File -> Settings -> Editor -> File Encodings来设置。...
服务器python项目部署
角色:root, 其他用户应该也可以 1. 安装python3环境 #如果是新机器,尽量执行,避免未知报错 yum -y update python -v yum install python3 python3 -v2. 使用virtualenvwrapper 创建虚拟环境,并使用workon切换不同的虚拟环境 # 安装virtua…...
3.6 登录认证
登录功能 登录思路 联调测试 登录校验 问题:在未登录情况下,我们也可以直接访问部门管理、员工管理等功能。 登录标记 用户登录成功之后,每一次请求中,都可以得到该标记。 统一拦截 过滤器Filter拦截器Interceptor 会话技术 会…...
OpenBMC:BmcWeb connect读取http请求
OpenBMC:BmcWeb构造connect对象-CSDN博客 OpenBMC:BmcWeb server.run-CSDN博客 1.构造了connect对象后,通过connection->start()开始处理来自客户端的请求 //http\http_connection.hpp void start() {...startDeadline();readClientIp();boost::beast::async_detect_ssl…...
金融合规测试:金融系统稳健运行的“定海神针“
一、什么是金融合规测试? 金融行业是受监管最严格的领域之一,各国政府和监管机构(如中国人民银行、银保监会、证监会、美国SEC、欧盟ESMA等)都制定了严格的法律法规,要求金融机构确保系统安全、交易透明、公平竞争&am…...
Nginx:从入门到实战使用教程
全方位解析Nginx:从入门到实战使用教程 Nginx安装、配置详细教程 文章目录 全方位解析Nginx:从入门到实战使用教程导语一、Nginx简介二、Nginx安装与配置 1. 在CentOS系统上安装Nginx:2. 在Ubuntu系统上安装Nginx:3. Nginx配置文…...
qt-C++笔记之ubuntu22.04源码安装Qt6.8.2
qt-C++笔记之ubuntu22.04源码安装Qt6.8.2 code review! 文章目录 qt-C++笔记之ubuntu22.04源码安装Qt6.8.21.作者环境:ubuntu22.04、cmake202.安装3.关联已安装的 Qt6 到 Qt Creator4.附:ubuntu18.0的处理,可尝试,作者没有遇到这个问题1.作者环境:ubuntu22.04、cmake20 安…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_modules
定义在 objs\ngx_modules.c #include <ngx_config.h> #include <ngx_core.h>extern ngx_module_t ngx_core_module; extern ngx_module_t ngx_errlog_module; extern ngx_module_t ngx_conf_module; extern ngx_module_t ngx_openssl_module; extern ngx_modul…...
简单的二元语言模型bigram实现
内容总结归纳自视频:【珍藏】从头开始用代码构建GPT - 大神Andrej Karpathy 的“神经网络从Zero到Hero 系列”之七_哔哩哔哩_bilibili 项目:https://github.com/karpathy/ng-video-lecture Bigram模型是基于当前Token预测下一个Token的模型。例如&#x…...
计算机视觉之dlib人脸关键点绘制及微笑测试
dlib人脸关键点绘制及微笑测试 目录 dlib人脸关键点绘制及微笑测试1 dlib人脸关键点1.1 dlib1.2 人脸关键点检测1.3 检测模型1.4 凸包1.5 笑容检测1.6 函数 2 人脸检测代码2.1 关键点绘制2.2 关键点连线2.3 微笑检测 1 dlib人脸关键点 1.1 dlib dlib 是一个强大的机器学习库&a…...
Windows11下玩转 Docker
一、前提准备 WSL2:Windows 提供的一种轻量级 Linux 运行环境,具备完整的 Linux 内核,并支持更好的文件系统性能和兼容性。它允许用户在 Windows 系统中运行 Linux 命令行工具和应用程序,而无需安装虚拟机或双系统。Ubuntu 1.1 安…...
Android 平台架构系统启动流程详解
目录 一、平台架构模块 1.1 Linux 内核 1.2 硬件抽象层 (HAL) 1.3 Android 运行时 1.4 原生 C/C 库 1.5 Java API 框架 1.6 系统应用 二、系统启动流程 2.1 Bootloader阶段 2.2 内核启动 2.3 Init进程(PID 1) 2.4 Zygote与System Serv…...
【C++设计模式】第四篇:建造者模式(Builder)
注意:复现代码时,确保 VS2022 使用 C17/20 标准以支持现代特性。 分步骤构造复杂对象,实现灵活装配 1. 模式定义与用途 核心目标:将复杂对象的构建过程分离,使得同样的构建步骤可以创建不同的表示形式。 常见场景&am…...
使用GitLink个人建站服务部署Allure在线测试报告
更多技术文章,访问软件测试社区 文章目录 🚀前言🔑开通GitLink个人建站服务1. 前提条件2. 登录GitLink平台(https://www.gitlink.org.cn/login)3. 进入设置>个人建站>我的站点4. 新建站点5. 去仓部进行部署6. 安…...
WHAT - 前端异步事件流处理场景梳理
目录 一、典型场景二、解决方案与技术选型1. 基础异步控制2. 状态管理方案3. 复杂任务调度4. 任务取消机制5. 微任务队列优化 三、最佳实践建议四、工具链推荐 前端异步任务流处理是现代Web开发中常见的需求,尤其在复杂业务逻辑、高交互性应用中不可或缺。以下是常见…...
专业学习|多线程、多进程、多协程加速程序运行
学习资料来源:【2021最新版】Python 并发编程实战,用多线程、多进程、多协程加速程序运行_哔哩哔哩_bilibili 若有侵权,联系删除。 一、程序的提速方法——多线程、多进程、多协程 在现代编程中,多线程、多进程和多协程是三种常见…...
C/C++蓝桥杯算法真题打卡(Day3)
一、P8598 [蓝桥杯 2013 省 AB] 错误票据 - 洛谷 算法代码: #include<bits/stdc.h> using namespace std;int main() {int N;cin >> N; // 读取数据行数unordered_map<int, int> idCount; // 用于统计每个ID出现的次数vector<int> ids; …...
烟花燃放安全管控:智能分析网关V4烟火检测技术保障安全
一、方案背景 在中国诸多传统节日的缤纷画卷中,烟花盛放、烧纸祭祀承载着人们的深厚情感。一方面,烟花璀璨,是对节日欢庆氛围的热烈烘托,寄托着大家对美好生活的向往与期许;另一方面,袅袅青烟、点点烛光&a…...
【Bert系列模型】
目录 一、BERT模型介绍 1.1 BERT简介 1.2 BERT的架构 1.2.1 Embedding模块 1.2.2 双向Transformer模块 1.2.3 预微调模块 1.3 BERT的预训练任务 1.3.1 Masked Language Model (MLM) 1.3.2 Next Sentence Prediction (NSP) 1.4 预训练与微调的关系 1.5 小结 二、BERT…...
9.1 Kubelet Eviction驱逐解读
驱逐文档 https://kubernetes.io/zh/docs/concepts/scheduling-eviction/node-pressure-eviction/ 驱逐的含义 节点压力驱逐是 kubelet 主动终止 Pod 以回收节点上资源的过程。这在处理内存和磁盘这种不可压缩资源时,驱逐pod回收资源的策略,显得尤为重…...
播放器系列4——PCM重采样
FFmpeg重采样过程 #mermaid-svg-QydNPsDAlg9lTn6z {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QydNPsDAlg9lTn6z .error-icon{fill:#552222;}#mermaid-svg-QydNPsDAlg9lTn6z .error-text{fill:#552222;stroke:#5…...
android接入rocketmq
一 前言 RocketMQ 作为一个功能强大的消息队列系统,不仅支持基本的消息发布与订阅,还提供了顺序消息、延时消息、事务消息等高级功能,适应了复杂的分布式系统需求。其高可用性架构、多副本机制、完善的运维管理工具,以及安全控制…...
《长文本处理新曙光:深入剖析多头隐式注意力机制显存优化奥秘》
在人工智能领域,Transformer架构无疑是璀璨的明星,为自然语言处理、计算机视觉等众多领域带来了革命性的变革。但Transformer架构在处理长文本时,其多头注意力机制(MHA)会产生显存占用呈几何级数增长的问题,…...
Spring Boot面试问答
1. Spring Boot 基础知识 问题 1:什么是Spring Boot?它与Spring框架有何不同? 回答: Spring Boot是基于Spring框架的一个开源框架,旨在简化新Spring应用的初始化和开发过程。与传统的Spring框架相比,Spring Boot提供了以下优势: 自动配置:根据项目依赖自动配置Spring…...
前端数据模拟 Mock.js 学习笔记
mock.js介绍 Mock.js是一款前端开发中拦截Ajax请求再生成随机数据响应的工具,可以用来模拟服务器响应 优点是:非常方便简单,无侵入性,基本覆盖常用的接口数据类型支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜…...
用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!
下载模型与数据 模型下载: huggingface: Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…...
DeepSeek大模型 —— 全维度技术解析
DeepSeek大模型 —— 全维度技术解析 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,可以分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/ccc 文章目录 DeepSeek大模型 —— 全维度技术解析一、模型架构全景解析1…...
DeepSeek + 沉浸式翻译 打造智能翻译助手
本文详细介绍如何使用 DeepSeek API 沉浸式翻译插件打造个性化翻译助手。 一、DeepSeek API 配置 基础配置 API 基础地址:https://api.deepseek.com需要申请 API Key支持与 OpenAI SDK 兼容的调用方式 可用模型 deepseek-chat:已升级为 DeepSeek-V3&am…...
