服务端面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

服务端阅读 06月2日 00:04

VSCode 快捷键怎么改?自定义键绑定和多快捷键方案切换

VSCode 的快捷键可以完全自定义,还能装不同平台的键位方案(Vim、Sublime、IntelliJ)让肌肉记忆无缝迁移。查看和搜索快捷键Ctrl+K Ctrl+S 打开快捷键设置面板。在这里可以:搜索命令名或快捷键组合修改任意命令的绑定查看冲突(同一个快捷键绑定了多个命令)搜索框里输入命令名(如 "format")或快捷键组合(先按 Ctrl+K 再按要搜索的键),快速定位。修改快捷键两种方式:方式一:面板里直接改。在快捷键面板里找到命令,双击或右键选 "Change Keybinding",按下新快捷键组合。方式二:编辑 keybindings.json。点击快捷键面板右上角的文件图标,打开 JSON 配置:// keybindings.json[ { "key": "ctrl+shift+f", "command": "editor.action.formatDocument", "when": "editorHasDocumentFormattingProvider && editorTextFocus" }, { "key": "ctrl+d", "command": "editor.action.copyLinesDownAction", "when": "editorTextFocus" }, { "key": "ctrl+shift+d", "command": "workbench.view.debug" }]when 条件控制快捷键在什么上下文生效——editorTextFocus 只在编辑器有焦点时生效,避免全局快捷键和终端冲突。常用快捷键调整建议格式化代码:默认 Shift+Alt+F,很多人改成 Ctrl+Shift+F 或 Ctrl+S 时自动格式化(配合 editor.formatOnSave: true)。复制当前行:默认 Shift+Alt+Down,改成 Ctrl+D 更顺手(但 Ctrl+D 默认是"添加下一个选中",改之前想清楚)。删除当前行:默认 Ctrl+Shift+K,可以改成 Ctrl+Shift+D 或其他顺手的组合。切换终端:Ctrl+` 比较远,可以加一组 Ctrl+J。装其他编辑器的键位方案不想一个个改?装键位扩展一键迁移:Vim:装 "VSCode Vim" 扩展,完整的 Vim 键位模拟Sublime Text:装 "Sublime Text Keymap" 扩展IntelliJ IDEA:装 "IntelliJ IDEA Keybindings" 扩展Emacs:装 "Emacs Friendly Keymap" 扩展装完扩展后,Ctrl+K Ctrl+S 面板里会显示对应编辑器的键位方案,可以和默认方案混用。when 条件常用值when 是快捷键自定义的关键——它决定快捷键在什么场景下生效:| when 值 | 含义 ||---------|------|| editorTextFocus | 编辑器有焦点 || terminalFocus | 终端有焦点 || resourceLangId == 'python' | 当前文件是 Python || editorHasSelection | 有选中文本 || inDebugMode | 调试模式中 |组合条件用 && 连接:editorTextFocus && resourceLangId == 'python' 表示只在编辑 Python 文件时生效。导出和同步快捷键VSCode Settings Sync(登录 GitHub 或 Microsoft 账号)自动同步快捷键配置到云端,换电脑不用重新配置。如果不想用云同步,手动复制 keybindings.json 文件也行。
服务端阅读 06月2日 00:04

VSCode 内置终端怎么用?分屏、多终端和配置技巧

VSCode 内置终端省去了在编辑器和终端窗口之间来回切换的麻烦。Ctrl+` 一键打开,和编辑器共享同一个窗口,代码和命令行并排操作。基本操作打开/关闭终端:Ctrl+`(反引号)或 View > Terminal新建终端:终端面板右上角的 + 号,或 Ctrl+Shift+`拆分终端:终端面板右上角的拆分图标,或 Ctrl+Shift+5,在同一个终端面板里左右分屏切换终端:终端面板右上角的下拉菜单选择,或 Ctrl+PageUp/PageDown拆分终端比新建标签页更实用——可以同时看着两个终端的输出,比如左边跑服务、右边看日志。终端类型选择VSCode 会自动检测系统上安装的 Shell:macOS:默认 zsh(Catalina 及以后),也可以选 bashLinux:默认 bash,也可以选 zsh/fishWindows:默认 PowerShell,也可以选 CMD 或 Git Bash手动选择默认终端:Ctrl+Shift+P 输入 Terminal: Select Default Profile,从列表中选择。指定特定终端:terminal.integrated.defaultProfile.osx/linux/windows 按平台设置。终端配置技巧// settings.json{ "terminal.integrated.fontSize": 14, "terminal.integrated.cursorStyle": "line", "terminal.integrated.scrollback": 5000, "terminal.integrated.copyOnSelection": true}scrollback: 5000 把回滚缓冲区从默认 1000 行增加到 5000 行,跑大量日志时不会丢失前面的输出。copyOnSelection 选中即复制,不用再 Ctrl+C。终端里的代码操作右键在终端中打开文件:如果终端输出了文件路径(比如编译错误 src/main.js:10:5),按住 Ctrl/Cmd 点击路径可以直接跳转到对应文件的对应行。选中终端文本:和普通终端不同,VSCode 终端选中文字不需要进入复制模式——直接鼠标拖选就行。运行选中代码:选中一段代码后,按 Shift+Enter 或右键选择 Run Selection in Python Terminal(需要 Python 扩展),代码直接在终端里执行。调试小段代码非常方便。任务运行器把常用命令绑定到任务里,不用每次手敲:// .vscode/tasks.json{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "npm run build", "group": "build", "problemMatcher": ["$tsc"] }, { "label": "dev", "type": "shell", "command": "npm run dev", "isBackground": true, "group": "none" } ]}Ctrl+Shift+P 输入 Tasks: Run Task 选择运行。problemMatcher 自动解析终端输出中的错误,标记到编辑器的 Problems 面板。常见问题终端字体乱码:Powerline 主题的特殊符号需要安装 Nerd Font。在设置里指定 terminal.integrated.fontFamily 为已安装的 Nerd Font 名称。终端启动慢:可能是 Shell 配置文件(.zshrc/.bashrc)加载太多东西。在终端里跑 time zsh -i -c exit 看启动耗时,超过 1 秒就该优化了。终端里 vim/nano 不能用:VSCode 终端不支持交互式程序的鼠标事件。如果需要在编辑器里用 vim,装 VSCode Vim 扩展而不是在终端里跑 vim。
服务端阅读 06月2日 00:02

VSCode IntelliSense 智能提示怎么用?代码补全、参数提示和自定义配置

IntelliSense 是 VSCode 的智能代码补全系统——输入几个字符就弹出建议列表,显示函数参数、类型信息、文档注释。不是所有语言的 IntelliSense 都一样强:TypeScript/Python 开箱即用,C++/Java 需要装扩展和配置。IntelliSense 提供什么输入代码时自动弹出的建议列表,不只是简单的文本补全,而是基于语义理解的:成员列表:输入 console. 后自动列出 log、error、warn 等方法参数信息:调用函数时显示参数名、类型和默认值,不用跳到定义去看快速信息:鼠标悬停(或按住 Option/Ctrl)显示变量类型、函数签名、文档注释代码片段:输入 for 后选择代码片段,自动生成完整的 for 循环结构触发方式:输入时自动弹出,或手动按 Ctrl+Space(macOS 可能冲突,可以在设置里改)。Ctrl+Shift+Space 手动触发参数提示。不同语言的支持程度开箱即用:TypeScript/JavaScript、Python、HTML/CSS、JSON。VSCode 内置了这些语言的 Language Server,装好就能用。需要装扩展:C/C++(装 Microsoft C/C++ 扩展)、Java(装 Language Support for Java)、Go(装 Go 扩展)、Rust(装 rust-analyzer)。扩展提供 Language Server,IntelliSense 的能力取决于扩展质量。几乎没有:纯文本、Shell 脚本(补全很有限)。这类语言没有类型系统,IntelliSense 能做的不多。让 IntelliSense 更好用调整触发行为// settings.json{ "editor.quickSuggestions": { "other": true, "comments": false, "strings": true }, "editor.suggestOnTriggerCharacters": true, "editor.acceptSuggestionOnCommitCharacter": true, "editor.snippetSuggestions": "top"}strings: true 在字符串里也能触发补全(写 import 路径时有用)。snippetSuggestions: "top" 把代码片段排到建议列表最前面。Tab 补全默认按 Tab 或 Enter 都能接受建议。如果你只想用 Enter 接受,防止误触 Tab:{ "editor.tabCompletion": "off", "editor.acceptSuggestionOnEnter": "on"}建议列表过滤建议列表支持模糊匹配——输入 clg 能匹配到 console.log。输入越具体,过滤越精准,不用滚列表找。常见问题IntelliSense 不工作:99% 的原因是 Language Server 没启动。看右下角状态栏有没有语言模式(比如 TypeScript),Ctrl+Shift+P 输入 Developer: Show Running Extensions 检查扩展是否正常加载。Python 补全慢:换用 Pylance 扩展(VSCode Python 扩展的默认 Language Server),比旧版 Jedi 快很多。在设置里确认 "python.languageServer": "Pylance"。C++ 头文件找不到:需要配置 c_cpp_properties.json,指定 include 路径。按 Ctrl+Shift+P 输入 C/C++: Edit Configurations 自动生成。建议列表太长:输入更具体的前缀过滤,或者在 editor.suggest.showWords 设为 false 关闭纯文本词语建议,只保留语义补全。进阶:GitHub CopilotCopilot 是 IntelliSense 的 AI 增强版——不只补全当前标识符,而是根据上下文生成整段代码。灰色幽灵文本预览建议,按 Tab 接受。和 IntelliSense 不冲突,两者同时工作:IntelliSense 提供精确的类型补全,Copilot 提供意图补全。
服务端阅读 06月2日 00:01

FFmpeg 是什么?能做什么?核心组件和常用命令入门

FFmpeg 是音视频领域的瑞士军刀——转码、剪辑、录屏、推流、截图、质量分析,一条命令搞定。它不是带界面的软件,而是命令行工具集,所有操作都在终端完成。OBS、VLC、YouTube 后台都用到了 FFmpeg。FFmpeg 能做什么转码:AVI 转 MP4、H.264 转 H.265、4K 降 1080p剪辑:截取视频片段、合并多个视频、去掉静音段录屏:录制屏幕和摄像头(macOS/Linux/Windows)推流:RTMP 直播推流、生成 HLS 流媒体截图:截取视频帧、批量生成缩略图分析:用 ffprobe 查看视频信息、用 PSNR/SSIM 评估画质核心组件FFmpeg 项目包含一组命令行工具和底层库:| 工具 | 用途 ||------|------|| ffmpeg | 转码、剪辑、推流(最常用) || ffprobe | 查看音视频文件信息(不转码,只分析) || ffplay | 简易播放器(调试用) |底层库(开发者在自己的程序中调用):| 库 | 功能 ||------|------|| libavformat | 处理封装格式(MP4、MKV、FLV…) || libavcodec | 编解码(H.264、AAC、VP9…) || libavutil | 通用工具函数 || libswscale | 图像缩放和色彩空间转换 || libswresample | 音频重采样 |日常只用 ffmpeg 和 ffprobe 两个命令。库是给开发者写程序用的,普通用户不用管。最常用的 5 条命令1. 格式转换ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp42. 视频剪辑ffmpeg -ss 00:01:00 -i input.mp4 -t 30 -c copy output.mp4从 1 分钟处截取 30 秒,-c copy 不重编码,秒级完成。3. 视频截图ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 screenshot.jpg截取第 5 秒的一帧。4. 查看视频信息ffprobe -v quiet -print_format json -show_format -show_streams input.mp4输出分辨率、码率、时长、编码格式等所有信息,JSON 格式方便脚本解析。5. 压缩视频ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow output.mp4CRF 28 比默认的 23 压得更狠,-preset slow 用更多编码时间换取更小的文件。安装# macOSbrew install ffmpeg# Ubuntu/Debiansudo apt install ffmpeg# Windows# 从 ffmpeg.org 下载,解压后把 bin 目录加到 PATH安装后跑 ffmpeg -version 确认可用。注意某些发行版的 FFmpeg 可能缺少某些编码器(如 libx265),需要从第三方源安装或自行编译。命令语法模式FFmpeg 命令的通用结构:ffmpeg [全局选项] [输入选项] -i 输入文件 [输出选项] 输出文件关键概念:选项的位置很重要。-ss 放在 -i 前面是快速跳转(不精确),放在后面是精确跳转(慢)。-c:v 和 -c:a 是输出选项,必须放在输出文件前面。
服务端阅读 06月2日 00:00

FFmpeg 视频转码怎么做?常用格式转换命令和参数详解

视频转码 = 解码 + 重新编码。最简单的形式是换个容器(MP4 转 MKV),最复杂的是同时改编码器、分辨率、码率、帧率。FFmpeg 一条命令搞定。最基本的转码# 让 FFmpeg 自动选择编码器(按输出文件后缀推断)ffmpeg -i input.avi output.mp4这样 FFmpeg 会自动把 AVI 里的 MPEG-4 视频转成 H.264,音频转成 AAC。简单但不可控——你不知道它选了什么参数。明确指定编码器:ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4-c:v 指定视频编码器,-c:a 指定音频编码器。这是转码命令的基本骨架,所有高级参数都加在这个基础上。常见转码场景AVI/MKV 转 MP4(最常见)ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4如果原视频已经是 H.264 编码,不需要重编码视频流,只换个容器:ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 128k output.mp4-c:v copy 直接拷贝视频流,几秒完成。但 MKV 支持的编码器比 MP4 多——如果 MKV 里是 H.265 或 VP9,copy 到 MP4 后部分播放器可能不兼容。转 WebM(网页视频)ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webmVP9 编码必须用 -b:v 0 配合 CRF 模式,否则 CRF 不生效。Opus 是 WebM 的标准音频编码器,音质优于 AAC。转 H.265(省空间)ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac -b:a 128k output.mp4H.265 的 CRF 28 大约等于 H.264 的 CRF 23,文件小 30-50%。编码慢 3-5 倍,老设备可能播不了。只转视频或只转音频# 只转视频,音频原样拷贝ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4# 只转音频,视频原样拷贝ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4# 去掉视频只保留音频ffmpeg -i input.mp4 -vn -c:a aac -b:a 128k output.aac-vn 去掉视频,-an 去掉音频,-sn 去掉字幕。转码时去掉不需要的流可以节省时间。硬件加速转码CPU 编码太慢?用 GPU 加速:# NVIDIA GPU(NVENC)ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -c:a aac output.mp4# Intel GPU(QSV)ffmpeg -hwaccel qsv -i input.mp4 -c:v h264_qsv -preset medium -c:a aac output.mp4# Apple Silicon(VideoToolbox)ffmpeg -hwaccel videotoolbox -i input.mp4 -c:v h264_videotoolbox -b:v 5M -c:a aac output.mp4硬件编码速度是 CPU 的 5-10 倍,但同码率下画质略差(约 5-10%)。如果追求极致画质用 CPU libx264,追求速度用 NVENC。-preset p4 是 NVENC 的质量档位,p1 最快 p7 最慢质量最好。转码时调分辨率和帧率# 1080p 转 720pffmpeg -i input.mp4 -vf "scale=1280:720" -c:v libx264 -crf 23 -c:a copy output.mp4# 保持宽高比,只限宽度ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:v libx264 -crf 23 -c:a copy output.mp4# 降帧率 60fps -> 30fpsffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a copy output.mp4-2 让 FFmpeg 自动计算高度保持比例,必须用偶数(有些编码器要求宽高都是偶数)。两遍编码:精确控制文件大小CRF 模式无法精确控制输出文件大小。如果需要视频刚好 100MB:# 第一遍:分析(不输出视频)ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 1 -an -f null /dev/null# 第二遍:实际编码ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 2 -c:a aac -b:a 128k output.mp4第一遍分析视频复杂度分布,第二遍据此分配码率。两遍编码比单遍 CRF 质量稍好,但编码时间翻倍。通常只在需要精确文件大小(如 DVD/蓝光)时才用。
服务端阅读 06月2日 00:00

FFmpeg 视频剪辑、合并和截图怎么做?常用命令速查

视频剪辑、合并、截图是 FFmpeg 最高频的日常操作。核心命令不多,但参数位置有讲究——放错位置效果完全不同。视频剪辑:截取片段最常用的剪辑命令# 从第 10 秒开始,截取 30 秒ffmpeg -ss 00:00:10 -i input.mp4 -t 30 -c copy output.mp4# 从 1:30 截到 3:00ffmpeg -ss 00:01:30 -to 00:03:00 -i input.mp4 -c copy output.mp4-c copy 直接拷贝音视频流,不重新编码,速度极快(几秒搞定),但切割点可能不精确——因为视频是按关键帧压缩的,-c copy 只能在关键帧处切开。结果可能是你想从 10 秒切,实际从 8 秒的关键帧开始了。精确剪辑需要精确到帧的剪辑,必须重新编码:ffmpeg -i input.mp4 -ss 00:00:10 -t 30 -c:v libx264 -crf 23 -c:a aac output.mp4去掉 -c copy,让 FFmpeg 重新编码。速度慢很多但切割点精确。-ss 放在 -i 前面还是后面?-ss 在 -i 前面:FFmpeg 先跳到指定时间再开始解码(seek 模式),速度快但可能不精确-ss 在 -i 后面:FFmpeg 从头解码到指定时间,精确但慢最佳实践:先放前面快速定位,再精确微调。对于长视频(>10 分钟),放前面能省很多时间。视频合并:拼接多个片段concat 协议(最快,要求格式完全一致)# 先创建文件列表echo "file 'part1.mp4'" > list.txtecho "file 'part2.mp4'" >> list.txtecho "file 'part3.mp4'" >> list.txt# 合并ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4-c copy 不重编码,秒级完成。但要求所有片段的编码参数(分辨率、帧率、编码器)完全一致,否则合并后可能花屏或播放异常。格式不一致时:先统一再合并# 先把所有片段转成统一格式for f in part*.mp4; do ffmpeg -i "$f" -c:v libx264 -crf 23 -c:a aac -b:a 128k -vf "scale=1920:1080" -r 30 "normalized_$f"done# 再用 concat 合并echo "file 'normalized_part1.mp4'" > list.txtecho "file 'normalized_part2.mp4'" >> list.txtffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4filter 复杂合并(加转场等效果)# 两个视频左右并排ffmpeg -i left.mp4 -i right.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2" output.mp4# 上下并排ffmpeg -i top.mp4 -i bottom.mp4 -filter_complex "[0:v][1:v]vstack=inputs=2" output.mp4filter 合并必须重编码,速度慢但能做各种效果。视频截图# 截取第 5 秒的一帧ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 screenshot.jpg# 每隔 10 秒截一张ffmpeg -i input.mp4 -vf "fps=1/10" screenshot_%04d.jpg# 截取多张(前 60 秒,每秒 1 帧)ffmpeg -i input.mp4 -t 60 -vf "fps=1" frame_%04d.jpgfps=1/10 表示每 10 秒一帧。%04d 是序号占位符,生成 screenshot0001.jpg、screenshot0002.jpg…截图的质量参数:-q:v 2(1 最好,31 最差,2 近乎无损)。ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -q:v 2 screenshot.jpg实用技巧去除视频静音段:用 silenceremove 滤镜自动剪掉没有声音的部分,适合处理会议录像。加速/减速视频:-vf "setpts=0.5*PTS" 2 倍速,-vf "setpts=2*PTS" 半速。音频也要对应调整:-af "atempo=2.0"(atempo 范围 0.5-2.0,超出需要串联)。旋转视频:-vf "transpose=1" 顺时针 90 度。手机竖拍视频在电脑上横着显示时用这个修正。
服务端阅读 06月1日 23:59

FFmpeg 直播推流怎么配?RTMP 推流和 HLS/DASH 流媒体生成实战

FFmpeg 是直播推流的核心工具——OBS 底层也是调用 FFmpeg 做编码和推流。直接用 FFmpeg 推流更轻量、更灵活,适合服务器端自动化场景。RTMP 推流:最常用的直播协议RTMP 是直播平台(B站、斗鱼、YouTube)的标准推流协议。核心命令:ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key关键参数:-re:按原始帧率读取输入,不加这个 FFmpeg 会以最快速度把文件读完然后全推出去,直播就变成了快进-preset veryfast:实时编码必须用快 preset,slow 的话编码速度跟不上帧率,画面会卡顿-b:v 2500k:固定码率 2.5Mbps,直播平台通常有码率上限(B站 6000k,YouTube 5100k)-f flv:RTMP 推流必须用 FLV 容器格式摄像头实时推流# macOS 摄像头 + 麦克风推流ffmpeg -f avfoundation -i "0:0" -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key# Linux 摄像头推流ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key摄像头推流比推文件更需要注意编码速度——如果 CPU 不够快,需要降低分辨率或码率:-vf "scale=1280:720" 降到 720p。HLS:苹果系的流媒体方案HLS 把视频切成小片段(.ts),通过 .m3u8 播放列表索引。延迟较高(通常 10-30 秒),但兼容性最好——所有浏览器和 iOS 设备都支持。ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f hls -hls_time 6 -hls_list_size 0 -hls_segment_filename "seg_%03d.ts" stream.m3u8关键参数:-hls_time 6:每个切片 6 秒,越短延迟越低但碎片越多-hls_list_size 0:播放列表包含所有切片(0 = 不限制),直播场景可以设成 5-10 只保留最近几个-hls_segment_filename:切片文件命名模板HLS 文件是纯静态文件,用 Nginx 或任何 HTTP 服务器托管就行,不需要专门的流媒体服务器。DASH:开源的流媒体方案DASH 和 HLS 类似,但基于 MPEG 标准,没有苹果的专利限制。浏览器支持不如 HLS(Safari 不原生支持 DASH),但功能更灵活。ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f dash -seg_duration 6 -out output.mpd实际上 DASH 在国内使用较少,大部分场景用 HLS 或 RTMP 就够了。多码率自适应推流给不同网速的用户提供不同清晰度——3G 用户看 480p,WiFi 用户看 1080p。用 -var_stream_map 生成多码率 HLS:ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v:0 5000k -s:v:0 1920x1080 -b:v:1 2500k -s:v:1 1280x720 -b:v:2 1000k -s:v:2 854x480 -c:a aac -b:a 128k -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" -f hls -hls_time 6 -master_pl_name master.m3u8 "stream_%v.m3u8"播放器会根据带宽自动切换码率,用户看到的效果就是网速慢时自动降清晰度。常见问题推流中断:网络波动导致 RTMP 连接断开。加 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 让 FFmpeg 自动重连,但不是所有版本都支持。延迟太高:HLS 延迟 10-30 秒是正常的。要低延迟用 RTMP 直推或 WebRTC(FFmpeg 不直接支持 WebRTC,需要 mediamtx 等中间件)。音视频不同步:通常是编码速度跟不上导致帧被丢弃。降低分辨率/码率,或者用更快的 preset。
服务端阅读 06月1日 23:57

FFmpeg 怎么录屏和录制摄像头?macOS/Linux/Windows 命令详解

FFmpeg 可以直接从屏幕或摄像头捕获视频,不需要额外安装录屏软件。命令行录制的好处是可以精确控制编码参数、方便脚本化、资源占用低。坏处是参数复杂,初次配置容易踩坑。macOS 录屏macOS 用 avfoundation 设备采集:# 列出可用设备(先看看屏幕和摄像头编号)ffmpeg -f avfoundation -list_devices true -i ""# 录制整个屏幕(假设屏幕编号是 1)ffmpeg -f avfoundation -i "1" -r 30 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制屏幕 + 系统音频ffmpeg -f avfoundation -i "1:0" -r 30 -c:v libx264 -preset ultrafast -crf 23 -c:a aac output.mp4-preset ultrafast 是录屏必备——实时编码用 slow 的话 CPU 扛不住,画面会卡。录完之后如果觉得文件太大,可以再用 slow preset 重新转码一遍。Linux 录屏Linux 用 x11grab 采集 X11 桌面:# 录制 1080p 屏幕ffmpeg -f x11grab -video_size 1920x1080 -framerate 30 -i :0.0 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制指定区域(从坐标 100,100 开始,宽 800 高 600)ffmpeg -f x11grab -video_size 800x600 -framerate 30 -i :0.0+100,100 -c:v libx264 -preset ultrafast -crf 23 output.mp4# Wayland 用户用 wf-recorder 更方便,ffmpeg 对 Wayland 支持不完善:0.0 是 DISPLAY 环境变量的值,多显示器时可能需要调整。Wayland 下 x11grab 可能不工作,需要装 xdotool 或者换用 wf-recorder。Windows 录屏Windows 用 gdigrab 或 dshow:# gdigrab 录制整个桌面ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -crf 23 output.mp4# 录制指定窗口ffmpeg -f gdigrab -framerate 30 -i title="Window Title" -c:v libx264 -preset ultrafast -crf 23 output.mp4Windows 10+ 也可以用 -f dshow 配合摄像头设备名录制。摄像头录制# macOS:列出设备后用摄像头编号(通常是 0)ffmpeg -f avfoundation -i "0" -r 30 -c:v libx264 -preset ultrafast -crf 23 output.mp4# Linux:用 v4l2ffmpeg -f v4l2 -video_size 640x480 -framerate 30 -i /dev/video0 -c:v libx264 -preset ultrafast -crf 23 output.mp4# 摄像头 + 麦克风ffmpeg -f avfoundation -i "0:0" -r 30 -c:v libx264 -preset ultrafast -crf 23 -c:a aac -b:a 128k output.mp4摄像头编号需要先 -list_devices true 查一下,不同机器编号可能不同。录屏实战技巧1. 录制时显示光标:默认录屏可能看不到鼠标光标。macOS 下加 -capture_cursor 1,Linux 下 x11grab 默认会包含光标。2. 控制录制时长:-t 60 只录 60 秒。方便做定时录制,不用手动按 Ctrl+C。3. 停止录制:按 Ctrl+C。有时候 ffmpeg 不会正常写入 MP4 尾部,导致文件打不开。解决办法:改用 MKV 容器(output.mkv),MKV 即使没正常关闭也能播放;或者事后修复 MP4:ffmpeg -i broken.mp4 -c copy fixed.mp44. 同时录屏和摄像头画中画:高级场景,用 overlay 滤镜把摄像头画面叠到屏幕录制上。这比纯录屏复杂很多,如果需要画中画效果,OBS 可能更合适。
服务端阅读 06月1日 23:56

FFmpeg 怎么批量转码?Shell 脚本和 Python 并行处理实战

单个文件用一条 ffmpeg 命令就行,但处理几十上百个文件就需要脚本了。批量处理的核心思路:用 Shell 循环遍历文件,用 GNU Parallel 做并行加速,用 Python 处理更复杂的逻辑。Shell 脚本:最简单的批量转码#!/bin/bash# 批量把 AVI 转成 MP4for file in *.avi; do ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "${file%.avi}.mp4"done${file%.avi} 是 Shell 的字符串截断——去掉 .avi 后缀,换成 .mp4。这个模式够用 80% 的批量场景。递归处理子目录里的文件:find /path/to/videos -name "*.mkv" | while read file; do ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "${file%.mkv}.mp4"donefind 递归搜索,while read 逐行读取文件路径。比 -exec 更灵活,可以在循环里加更多逻辑。并行加速:别让 CPU 闲着单线程循环太慢——4 核 CPU 只用了 1 核。用 GNU Parallel 让多个 ffmpeg 同时跑:# 4 个 ffmpeg 并行转码find . -name "*.avi" | parallel -j 4 ffmpeg -i {} -c:v libx264 -crf 23 -c:a aac {.}.mp4{} 是输入文件名,{.} 是去掉后缀的文件名。-j 4 限制并发数——设成 CPU 核心数就行,太多会抢 IO 反而变慢。没有 GNU Parallel?用 xargs 也能并行:find . -name "*.avi" | xargs -P 4 -I {} sh -c 'ffmpeg -i "$1" -c:v libx264 -crf 23 -c:a aac "${1%.avi}.mp4"' _ {}-P 4 控制并发数,-I {} 指定占位符。Python:更灵活的批量处理Shell 脚本能做的事 Python 都能做,而且更容易处理错误和复杂逻辑:import subprocess, os, globinput_dir = "raw"output_dir = "compressed"os.makedirs(output_dir, exist_ok=True)for path in glob.glob(f"{input_dir}/*.mp4"): name = os.path.basename(path) output = os.path.join(output_dir, name) cmd = ["ffmpeg", "-i", path, "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-b:a", "128k", "-movflags", "+faststart", output] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: print(f"OK {name}") else: print(f"FAIL {name}: {result.stderr[:200]}")Python 的优势:可以记录成功/失败、跳过已处理文件、按条件选不同参数。Shell 脚本做这些需要大量 if-else,可读性差。进阶:按条件选择不同参数不同类型的视频用不同的压缩策略——教学录屏用高 CRF + stillimage,电影用低 CRF + film:#!/bin/bashfor file in *.mp4; do duration=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$file" | cut -d. -f1) if [ "$duration" -lt 300 ]; then ffmpeg -i "$file" -c:v libx264 -crf 28 -tune stillimage -c:a aac "compressed_$file" else ffmpeg -i "$file" -c:v libx264 -crf 23 -tune film -c:a aac "compressed_$file" fidone跳过已处理文件批量中断后重跑,不想重复处理已经转好的文件:for file in *.mp4; do output="output/$file" [ -f "$output" ] && continue ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "$output"done一行判断搞定断点续传。Python 版可以用 os.path.exists() 做同样的事。
服务端阅读 06月1日 23:26

FFmpeg 视频格式和编解码器怎么选?MP4、MKV、WebM 各适合什么场景?

选视频格式就是选容器(封装格式),选编解码器就是选压缩算法。容器决定兼容性和功能(能不能塞字幕、多音轨),编解码器决定画质和文件大小。两者要分开想。容器格式:MP4、MKV、WebM 怎么选MP4:万能格式,所有设备都能播。缺点是只支持有限的编解码器,多音轨多字幕支持弱。网络视频、手机分享、社交媒体一律选 MP4,不会有兼容性问题。MKV:万能容器,什么编解码器都能塞,支持无限音轨和字幕轨。缺点是某些老旧设备和播放器不支持(特别是智能电视和游戏机)。本地收藏、多语言视频、高清片源选 MKV。WebM:Google 推的 Web 专用格式,基于 VP8/VP9/AV1 编码。所有主流浏览器支持,不需要插件。网页嵌入视频选 WebM,或者直接用 MP4(浏览器也支持)。MOV:Apple 的格式,QuickTime 原生支持。在 Mac 生态里很方便,但 Windows 上不如 MP4 通用。视频剪辑工作流里常见(Final Cut Pro 默认输出 MOV)。编解码器:H.264、H.265、AV1 怎么选H.264(AVC):兼容性之王,所有设备都支持。压缩效率中等,是目前的默认选择。如果你不确定该用什么,用 H.264 不会错。ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4H.265(HEVC):比 H.264 同画质小 30-50%,但编码慢 3-5 倍。兼容性不如 H.264——老手机、老浏览器可能播不了。4K 视频和存档用 H.265,因为省的空间很可观。Windows 10+ 和近三年的手机基本都支持了。ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac output.mp4AV1:新一代编码,比 H.265 还能再省 20-30%。开源免专利费,YouTube 和 Netflix 都在用。但编码极慢(libaom-av1 比 libx265 慢 10 倍以上),播放需要较新的硬件/软件。2025 年的 AV1 已经可以在最新设备上流畅播放,但离全面普及还有距离。如果追求极致压缩且目标平台新,可以试试。ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -c:a libopus output.webm音频编解码器视频里的音频也别忽略:AAC:通用选择,所有设备支持,128kbps 够听Opus:开源编码器,同码率音质优于 AAC,WebM 默认音频编码MP3:老旧但兼容性极好,新项目不需要用了# 视频 H.264 + 音频 AAC(最通用组合)ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4# 只转音频,视频直接拷贝ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4选择决策流程目标平台是什么?网页 → MP4/WebM,手机分享 → MP4,本地存档 → MKV需要兼容老设备吗?是 → H.264,否 → H.265/AV1对文件大小敏感吗?是 → H.265 CRF 28,否 → H.264 CRF 23需要多音轨/多字幕吗?是 → MKV,否 → MP4最常见组合:H.264 + AAC 封装成 MP4,覆盖 99% 的播放场景。
服务端阅读 06月1日 23:25

FFmpeg 怎么查看视频信息?ffprobe 命令和视频质量分析实战

获取视频信息用 ffprobe(FFmpeg 自带的探测工具),不需要转码,秒出结果。分析视频质量用 PSNR/SSIM 等指标,对比编码前后的画质差异。ffprobe:一行命令看透视频最常用的命令:# 查看所有信息(人类可读)ffprobe input.mp4# JSON 格式输出(方便脚本解析)ffprobe -v quiet -print_format json -show_format -show_streams input.mp4日常只需要几个关键字段:| 字段 | 含义 | 查看命令 ||------|------|----------|| 分辨率 | 视频宽高 | ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 input.mp4 || 时长 | 视频长度(秒) | ffprobe -v error -show_entries format=duration -of csv=p=0 input.mp4 || 码率 | 比特率 | ffprobe -v error -show_entries format=bit_rate -of csv=p=0 input.mp4 || 帧率 | 每秒帧数 | ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of csv=p=0 input.mp4 || 编码器 | 编解码格式 | ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 input.mp4 |这些命令看着长,但本质都是 -show_entries 指定要哪个字段 + -of 指定输出格式。记住模式就行,不用背命令。提取关键信息的快捷脚本# 一行获取:分辨率 帧率 编码 时长 码率ffprobe -v error -select_streams v:0 \ -show_entries stream=width,height,codec_name,r_frame_rate \ -show_entries format=duration,bit_rate \ -of default=noprint_wrappers=1 input.mp4在 Python 里调用 ffprobe:import subprocess, jsondef get_video_info(path): cmd = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", path] result = subprocess.run(cmd, capture_output=True, text=True) return json.loads(result.stdout)info = get_video_info("input.mp4")video = info["streams"][0] # 第一个视频流print(f"分辨率: {video["width"]}x{video["height"]}")print(f"编码: {video["codec_name"]}")print(f"时长: {float(info["format"]["duration"]):.1f}秒")视频质量分析:量化编码损失压缩视频后想知道画质损失了多少,用 PSNR 和 SSIM 两个指标。PSNR(峰值信噪比):数值越高画质越好,30dB 以下明显有损,40dB 以上视觉无损。ffmpeg -i original.mp4 -i compressed.mp4 -lavfi psnr -f null -SSIM(结构相似度):0-1 之间,越接近 1 越相似。SSIM 比 PSNR 更接近人眼感知——PSNR 只看像素差异,SSIM 看结构变化。实际评估画质优先看 SSIM。ffmpeg -i original.mp4 -i compressed.mp4 -lavfi ssim -f null -两个命令都会逐帧计算并输出平均值。VMAF 是 Netflix 提出的更先进的质量指标,更接近人类主观评分,但 FFmpeg 原生不支持(需要额外编译 libvmaf)。常见问题排查视频打不开:先跑 ffprobe input.mp4,看报错信息。常见原因:文件损坏、编码不支持、容器格式错误。ffprobe 比任何播放器都能更快定位问题。码率异常:如果视频文件很大但画质一般,用 ffprobe 看码率——可能是编码效率低(用了老编码器)或码率设置过高。转成 H.264/265 + 合理 CRF 通常能大幅缩小。音视频不同步:ffprobe 看 start_time 差异——音频和视频的起始时间不一致就会导致不同步。
服务端阅读 06月1日 23:24

FFmpeg 视频压缩怎么选参数?CRF、preset 和 tune 实战指南

FFmpeg 压缩视频的核心就三个参数:-crf 控制质量,-preset 控制编码速度和压缩率的平衡,-tune 针对特定内容类型优化。理解这三个参数,就能应对 90% 的压缩场景。CRF:画质旋钮CRF(Constant Rate Factor)是 H.264/H.265 的质量控制参数,范围 0-51。数字越小质量越高文件越大,数字越大质量越低文件越小。关键参考值:18:视觉无损,和原片几乎看不出差别,文件很大23:默认值,质量和体积的平衡点,大多数场景够用28:明显有损但能看,适合手机端播放30+:质量较差,只在极端节省空间时使用ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4CRF 是感知质量恒定——运动多的场景自动多分配码率,静态场景少分配。所以同一个 CRF 值,不同视频的文件大小可能差很多。如果需要精确控制文件大小,得用两遍编码(two-pass)或指定码率。Preset:时间换空间Preset 控制编码器用多少计算时间来寻找更优的压缩方案。越慢的 preset 压缩率越高(同画质文件更小),但编码时间越长。| Preset | 编码速度 | 同 CRF 文件大小 | 适用场景 ||--------|----------|-----------------|----------|| ultrafast | 最快 | 最大(约 2x) | 实时流媒体 || veryfast | 很快 | 较大 | 直播推流 || fast | 快 | 中等 | 日常快转 || medium | 中等(默认) | 基准 | 一般用途 || slow | 慢(约 3x 时间) | 较小(约 -15%) | 离线转码 || veryslow | 很慢(约 6x) | 更小(约 -25%) | 归档存储 |实际建议:离线处理用 slow,实时场景用 veryfast,不确定就用 medium。ultraslow 不存在,veryslow 已经是极限了。从 medium 切到 slow,编码时间翻 3 倍但文件只小 15%——值不值看你的需求。# 离线高质量压缩ffmpeg -i input.mp4 -c:v libx264 -crf 20 -preset slow output.mp4# 快速压缩(直播/即时预览)ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset veryfast output.mp4Tune:针对性优化Tune 让编码器针对特定内容类型调整策略:film:电影/真人视频,去胶片颗粒感,优化暗部细节animation:动画片,优化大面积色块和平滑区域stillimage:PPT 录屏/幻灯片,优化静态画面fastdecode:牺牲一点压缩率换取更快解码速度(低端设备播放)zerolatency:零延迟,实时流媒体和直播专用大部分情况不加 tune 就行。加错了反而比不加差——对真人视频用 animation,细节会糊掉。# 压缩电影ffmpeg -i movie.mkv -c:v libx264 -crf 20 -preset slow -tune film output.mp4# 压缩动画ffmpeg -i anime.mkv -c:v libx264 -crf 20 -preset slow -tune animation output.mp4# 压缩录屏教程ffmpeg -i screen.mp4 -c:v libx264 -crf 23 -preset medium -tune stillimage output.mp4H.265 压缩:省空间但要考虑兼容性H.265(HEVC)比 H.264 同画质文件小 30-50%,但编码慢 3-5 倍,且老设备可能不支持播放。如果目标平台是手机/智能电视/浏览器,H.264 兼容性最好。如果目标是存档或只在 PC 上播放,H.265 更划算。ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset slow output.mp4注意 H.265 的 CRF 值不能和 H.264 直接对比——H.265 的 CRF 28 大致对应 H.264 的 CRF 23,因为 H.265 的范围和感知曲线不同。两个常见坑1. 忘了 -movflags +faststart:MP4 文件的元数据(moov atom)默认放在文件末尾,浏览器必须下载完整个文件才能开始播放。加 -movflags +faststart 把元数据移到开头,允许边下载边播放。网络视频必加。2. 音频不要忘:压缩视频时音频默认也会被重编码。如果只是压缩视频不想动音频,加 -c:a copy 直接拷贝音频流。要压缩音频就用 -c:a aac -b:a 128k,128kbps 对大多数内容够用。
服务端阅读 06月1日 23:20

NLP(自然语言处理)是什么?核心技术从规则到 LLM 怎么演变的?

自然语言处理(Natural Language Processing,NLP)是让计算机理解、解释和生成人类语言的技术。你用的搜索引擎、翻译软件、智能客服、ChatGPT,背后都是 NLP。NLP 解决什么问题NLP 的任务可以分两大类:理解(从文本中提取信息)和生成(产出新的文本)。理解类任务:文本分类(这封邮件是不是垃圾邮件)、命名实体识别(提取人名地名)、情感分析(这条评论是正面还是负面)、问答(从文档中找到答案)。这类任务的核心是把非结构化的文本变成结构化的信息。生成类任务:机器翻译、文本摘要、对话生成、代码生成。这类任务不仅要理解输入,还要产出流畅、连贯、准确的新文本。生成比理解难得多——理解只需要判断对错,生成要在一个天文数字的候选空间里选出最好的。NLP 技术的三个时代规则时代(1950s-1990s):手写语法规则和词典。专家系统写几千条 if-else 规则来解析句子。准确率在小领域内还行,但覆盖面极窄——换个领域规则全废,维护成本爆炸。统计机器学习时代(1990s-2012):从数据中自动学习规律。HMM 做词性标注,CRF 做序列标注,SVM 做分类。关键突破是特征表示——词袋模型、TF-IDF、N-gram 把文本变成了数值向量。但特征仍然需要人工设计,模型能力的天花板就是特征工程的质量。深度学习时代(2013-至今):神经网络自动学特征,不需要手工设计。Word2Vec 让词有了语义向量表示("国王" - "男人" + "女人" ≈ "女王"),RNN/LSTM 处理变长序列,CNN 做文本分类。2017 年 Transformer 出现后,NLP 的范式彻底变了——BERT、GPT 用预训练+微调替代了从零训模型,LLM 用提示词替代了微调本身。NLP 的核心 Pipeline传统 NLP 系统的典型流程:文本 → 预处理(清洗、分词)→ 特征提取(词向量、句向量)→ 模型推理 → 后处理。每一步都需要单独优化,错误会在步骤间传播——分词错了,下游全错。LLM 时代 Pipeline 大幅简化:文本 → tokenizer → LLM 推理 → 输出。分词、特征提取、模型推理都压缩进了一个端到端的过程。代价是计算成本更高,但换来的是更少的手工环节和更好的效果。中文 NLP 的特殊挑战中文没有空格分隔词语,分词是所有下游任务的前提。jieba 是最常用的分词工具,但准确率约 90%,专业领域需要自定义词典。另一个问题是中文的指代消解——"他"指谁?"这家公司"指哪家?英文有性别代词做线索,中文的"他/她/它"发音相同,歧义更多。NLP 当前最热的方向RAG(检索增强生成):让 LLM 先检索外部知识库再生成回答,解决幻觉问题。Agent:让 LLM 调用工具、规划步骤、自主执行任务。多模态:同时处理文本、图像、语音。小模型蒸馏:把大模型的能力压缩到小模型里,降低部署成本。这些方向都建立在 Transformer 和 LLM 的基础上——理解了底层原理,上面的应用方向只是组合方式不同。
服务端阅读 06月1日 23:19

Transformer 架构是怎么工作的?自注意力、位置编码和残差连接详解

Transformer 是 2017 年 Google 在《Attention is All You Need》里提出的架构,用纯注意力机制替代了 RNN 和 CNN 做序列建模。它是 BERT、GPT 以及所有现代大语言模型的基础。核心思想:注意力替代递归RNN 处理序列要一步一步来——看第 3 个词之前必须先处理第 1 和第 2 个词。这导致两个问题:无法并行训练,长距离依赖会衰减(梯度消失)。Transformer 的解决方案是:让每个位置直接和所有其他位置交互,一步到位。不需要逐步递归,训练时所有位置可以并行计算——GPU 最擅长这种矩阵运算。自注意力:序列中的每个词和所有词交互对序列中的每个词,自注意力计算它和其他所有词的相关性(注意力权重),然后按权重聚合信息。具体来说:每个词生成三个向量——Query(我在找什么)、Key(我能提供什么)、Value(我的实际内容)。Query 和所有 Key 做点积得到相关性分数,softmax 归一化后对 Value 加权求和。Attention(Q, K, V) = softmax(QK^T / √d_k) V除以 √d_k 是缩放,防止点积太大导致 softmax 输出接近 one-hot(梯度几乎为零)。这个缩放因子是"Scaled Dot-Product Attention"里"Scaled"的由来。多头注意力:同时学多种关系一个注意力头只能学一种关联模式。但语言中有语法关系、语义关系、位置关系等多种层次。多头注意力让每个头独立学习不同的模式——8 个头就学 8 种不同的"怎么看句子"的方式,最后拼接起来。实验上,多头注意力的效果显著优于单头。但头数不是越多越好,通常和模型维度一起调。GPT-3 用了 96 个头,但那是因为模型维度是 12288——每个头的维度是 128,和原始论文一致。位置编码:没有递归,怎么知道词的顺序自注意力本身是排列不变的——打乱输入顺序,输出只是对应的排列,值不变。但"猫吃鱼"和"鱼吃猫"意思完全不同,模型必须知道词的顺序。Transformer 用正弦/余弦函数生成位置编码,和词嵌入相加。为什么用三角函数?因为它有相对位置的性质:PE(pos+k) 可以用 PE(pos) 的线性变换表示,这让模型更容易学习相对位置关系。后来的模型用了可学习的位置编码(BERT、GPT 都是),直接让模型自己学一组位置向量。RoPE(旋转位置编码)是更新的方案,被 LLaMA 等模型采用,能更好地泛化到训练时没见过的序列长度。残差连接和层归一化每个 Transformer 层的输出 = LayerNorm(x + Sublayer(x)),其中 Sublayer 是注意力或前馈网络。残差连接(+x)让梯度可以直接回传,避免深层网络梯度消失。层归一化(LayerNorm)稳定训练,防止每层的输出分布漂移。注意归一化的位置:原始 Transformer 是 Post-LN(先 Sublayer 再 LN),后来发现 Pre-LN(先 LN 再 Sublayer)训练更稳定,GPT 和大多数现代模型都用 Pre-LN。编码器-解码器结构原始 Transformer 用于机器翻译,包含编码器和解码器:编码器:双向自注意力 + 前馈网络,理解源语言解码器:单向自注意力(遮住未来信息)+ 交叉注意力(看编码器输出)+ 前馈网络,生成目标语言但后来的发展证明不需要两者都用:BERT 只用编码器(理解任务),GPT 只用解码器(生成任务),T5 保留了完整的编码器-解码器。2024 年的趋势是纯解码器架构一统天下——解码器通过指令微调也能做理解任务,何必维护两个模块?前馈网络:注意力的补充每层还有一个两层的前馈网络:FFN(x) = W2·ReLU(W1·x)。FFN 的隐藏维度通常是模型维度的 4 倍(如 d_model=768 时 FFN 维度=3072)。自注意力负责词和词之间的关系,FFN 负责每个位置内部的非线性变换。可以理解为:注意力做信息路由(把相关信息拉过来),FFN 做信息加工(把拉过来的信息消化掉)。研究表明 FFN 层存储了大部分的"知识"(事实记忆),而注意力层更多在做"逻辑"(关系推理)。
服务端阅读 06月1日 23:18

BERT 和 GPT 有什么区别?为什么一个擅长理解一个擅长生成?

BERT 用 Transformer 编码器,GPT 用 Transformer 解码器。这一个选择决定了它们的所有差异:BERT 双向看上下文(适合理解),GPT 只看上文(适合生成)。架构选择:编码器 vs 解码器Transformer 原论文有编码器和解码器两部分。编码器的自注意力是双向的——处理"苹果"这个词时,"苹果"前后所有词都能看到。解码器的自注意力是单向的(也叫因果注意力)——只能看到当前词和它之前的词,后面的词被遮住。BERT 选了编码器,因为它要做的是"完形填空":遮住一些词,根据前后文预测。双向注意力让模型能同时利用左右两侧的上下文信息。GPT 选了解码器,因为它要做的是"续写":给定前文,预测下一个词。单向注意力保证训练和推理的一致性——推理时确实只能看到已生成的前文。如果用双向注意力,训练时能看到"未来"但推理时看不到,就会产生不一致。训练目标:MLM vs CLMBERT 的掩码语言模型(MLM):随机遮住 15% 的 token,让模型预测被遮住的词。这就像做完形填空——"The [MASK] sat on the mat",模型要预测 [MASK] 是 "cat"。BERT 还加了一个下一句预测(NSP)任务,判断两个句子是否相邻,但后来的研究表明 NSP 其实没太大用,RoBERTa 去掉 NSP 反而效果更好。GPT 的因果语言模型(CLM):给定前文,预测下一个 token。这天然就是一个生成任务——每个词都是基于前面所有词的概率分布选出来的。GPT 的训练目标简单粗暴,但规模大了之后涌现出了 BERT 做不到的能力:in-context learning(上下文学习)、chain-of-thought reasoning(链式推理)。能力差异的本质BERT 强在理解:文本分类、NER、问答(抽取式)、语义匹配。这些任务不需要生成新文本,只需要对已有文本做判断。双向注意力让 BERT 看到了完整的上下文,判断更准确。GPT 强在生成:对话、翻译、代码生成、创意写作。这些任务需要一步步产出新内容,单向注意力的自回归方式和生成任务天然契合。而且 GPT 的生成能力随规模非线性增长——GPT-2 只能写连贯的短文,GPT-3 能做 few-shot learning,GPT-4 能做复杂推理。这种涌现能力是 BERT 架构做不到的。一句话总结:BERT 是最好的阅读理解者,GPT 是最好的写作高手。2024-2025 的格局BERT 系列在工业界仍然广泛使用——分类、NER 这些任务用 BERT 微调又快又便宜,768 维的 BERT-base 推理一次只要几毫秒。但新项目越来越倾向直接用 LLM API(GPT-4/Claude)+ prompt engineering 替代 BERT 微调,因为省掉了标注数据和训练的成本。GPT 阵营这边,开源模型(LLaMA、Mistral、Qwen、DeepSeek)已经可以在本地跑,7B 参数的模型在一台消费级 GPU 上就能推理。闭源模型(GPT-4o、Claude Sonnet、Gemini)在能力上仍然领先,但差距在缩小。一个值得注意的趋势:编码器-解码器架构(T5、BART)正在被纯解码器架构取代。T5 最初证明了解码器也能做理解任务,后来大家发现直接用 GPT 架构加指令微调就能同时搞定理解和生成,何必用两个模块?
服务端阅读 06月1日 15:05

注意力机制是什么?为什么 Transformer 靠它替代了 RNN?

注意力机制让模型在处理每个词时,能动态决定该"看"输入序列的哪些其他词。它是 Transformer 的核心,也是 BERT、GPT 等现代 NLP 模型的基础。没有注意力机制,就没有今天的大语言模型。直觉:注意力在做什么想象你在读"银行"这个词,想理解它的意思。如果上下文是"他去银行存钱","银行"和"存钱"的关系最密切——你的注意力会聚焦在"存钱"上。如果上下文是"他坐在河的银行边",注意力会转向"河"。注意力机制做的就是这个:对序列中的每个位置,计算它和其他所有位置的相关程度,然后按相关程度加权聚合信息。相关程度高的权重大,低的权重小。核心计算:Query、Key、Value注意力机制借用了数据库检索的概念:Query(Q):当前词想知道"我应该关注谁"Key(K):每个词提供的"我是谁、我有什么信息"Value(V):每个词实际传递的信息内容计算过程:Q 和每个 K 做点积,得到相关性分数 → 除以 √d_k(缩放,防止点积太大导致 softmax 梯度消失)→ softmax 归一化成权重 → 用权重对 V 加权求和,得到输出。公式:Attention(Q, K, V) = softmax(QK^T / √d_k) V为什么 Q·K^T 能代表相关性?因为它们是学出来的向量——训练过程中,相关的 Q 和 K 会被调整到点积更大的方向,不相关的被调到点积更小的方向。点积只是度量相似性的工具,真正的知识在 Q 和 K 的参数里。自注意力 vs 交叉注意力自注意力:Q、K、V 都来自同一个序列。模型在处理一个句子时,让每个词和句子中所有其他词交互。这是 Transformer 编码器的核心——BERT 全靠自注意力理解上下文。交叉注意力:Q 来自一个序列,K 和 V 来自另一个序列。典型场景是机器翻译:Q 来自目标语言(正在生成的词),K 和 V 来自源语言(待翻译的句子)。交叉注意力让模型在生成每个目标词时,"回头看"源句子的哪个部分最相关。多头注意力:为什么不只用一个注意力一个注意力头只能学一种关联模式。但语言中有多层关系:语法关系(主语-谓语)、语义关系(同义词)、位置关系(相邻词)。多头注意力让模型同时学多种模式——每个头独立计算 Q/K/V,最后拼接起来。Transformer 原论文用了 8 个头,GPT-3 用了 96 个头。头数不是越多越好,太小不够表达,太大参数浪费,通常和模型维度一起调。注意力为什么替代了 RNNRNN 的致命问题是顺序依赖:处理第 t 个词必须先处理完前 t-1 个词,无法并行。序列长了梯度消失/爆炸,LSTM 的门机制缓解但没根治。注意力一步到位:每个位置直接和所有位置交互,不需要逐步递归,训练时完全并行。GPU 最擅长的就是并行矩阵运算——注意力的 QK^T 计算就是大矩阵乘法,GPU 跑起来飞快。代价是 O(n²) 的计算和内存复杂度——序列长度翻倍,计算量翻四倍。这就是为什么早期 BERT 只支持 512 token,直到 FlashAttention 等优化技术出现才突破了长序列的瓶颈。实际影响注意力机制不只是 Transformer 的一个组件,它改变了整个 NLP 的范式。RNN 时代,模型架构是瓶颈;注意力时代,瓶颈变成了数据和算力。从 BERT 到 GPT-4,底层都是注意力机制,差别只在规模和训练策略。
服务端阅读 06月1日 15:04

如何构建一个 NLP 系统?从数据到部署的完整流程

构建 NLP 系统不只是训模型——从数据收集到线上服务,中间有大量工程决策要做。模型只是系统的一部分,很多时候瓶颈不在模型效果,而在数据处理、服务稳定性和迭代速度上。明确任务和指标先想清楚三件事:系统要解决什么问题?怎么衡量效果?兜底策略是什么?比如做一个客服意图分类系统:目标是自动识别用户咨询的类别(退款、物流、产品问题等),指标是 F1 值和人工介入率,兜底是置信度低于阈值就转人工。不要上来就想用最先进的模型,先把任务定义清楚。数据工程数据是 NLP 系统的地基,也是最容易出问题的地方。数据收集:业务日志、用户生成内容、公开数据集。优先用业务数据——它最贴近真实场景。公开数据集可以做冷启动,但分布往往和线上不一致,上线后效果会打折。数据标注:标注质量直接决定模型上限。找领域专家标注,别找众包工人——一个律师标的法律文本和一个大学生标的,质量天差地别。标注指南要写清楚边界案例("苹果"在什么语境下是公司,什么语境下是水果),标注一致性(多人标同一批数据的重合度)至少要 85% 以上。数据版本管理:每次训练用的数据集要能追溯。DVC 或简单的 git + 文件哈希都行。线上出了问题,你得知道当时模型是用哪批数据训的。模型开发选模型:2025 年的默认选择是 BERT 系列做理解任务,GPT 系列做生成任务。小数据量(<1万条)用预训练模型微调,极少数据(<100条)考虑 few-shot prompt 或 LLM API。别从零训模型——预训练成本百万美元起步,除非你是大厂。训练技巧:学习率用 2e-5 起,batch size 小就梯度累积。早停比固定 epoch 好。保存最优 checkpoint 而不是最后一个。混合精度训练(FP16)省一半显存,几乎不损失效果。评估:离线指标(F1、BLEU、ROUGE)只是参考,必须做线上 A/B 测试。离线 F1 从 85 提到 87,线上可能完全没差别——因为测试集和真实分布不一样。服务化部署API 封装:FastAPI 是最简单的选择,异步、自动生成文档、类型检查。模型推理用 ONNX Runtime 或 TensorRT 加速,比原生 PyTorch 快 3-10 倍。批处理 vs 实时:搜索引擎这种场景可以批处理(离线算好存索引),客服对话必须实时推理(用户等不了)。实时推理要控制延迟——P99 低于 200ms 是基本要求。模型版本管理:线上同时跑多个版本,灰度切流量。出了问题秒级回滚。用 A/B 测试比较新旧版本的业务指标,别靠感觉。监控和迭代上线才是开始。监控三件事:输入分布变化(用户开始说之前没见过的话术)、模型置信度下降(突然大面积低置信度说明有新问题)、业务指标波动。建立数据飞轮:线上低置信度的样本 → 人工标注 → 补充训练集 → 重新训练。好的 NLP 系统不是一次训好的,是持续迭代出来的。每个版本的数据、模型、效果都要能追溯,这样出了问题才能定位原因。
服务端阅读 06月1日 15:03

命名实体识别(NER)怎么做?BiLSTM-CRF 和 BERT-CRF 哪个好?

命名实体识别(Named Entity Recognition,NER)是从文本中抽取出特定类型的实体——人名、地名、机构名、日期等。它是信息抽取的基础:搜索引擎要理解"苹果"是公司还是水果,问答系统要找到答案里的人名和地点,都靠 NER。NER 怎么定义"实体"最常用的标注体系是 BIO:B-X 表示实体 X 的开头,I-X 表示实体 X 的内部,O 表示非实体。比如"北京大学位于海淀区"标注为"B-ORG I-ORG I-ORG I-ORG O B-LOC I-LOC I-LOC"。还有 BIOES 体系多了 E(结束)和 S(单字实体),理论上更精确但实际差距不大。常见实体类型:PER(人名)、LOC(地名)、ORG(机构)、DATE(日期)、MISC(其他)。具体定义取决于业务场景——医疗 NER 需要识别疾病名和药品名,金融 NER 需要识别公司名和指标。NER 方法演进规则和词典:正则匹配+实体词典,准确率极高但覆盖率低。电话号码、邮箱这类格式固定的实体用正则就行。但新实体(新人名、新公司名)永远识别不了——这就是规则方法的根本缺陷。CRF(条件随机场):传统方法的巅峰。它考虑整个序列的标签联合概率,避免"I-ORG"跟在"O"后面这种非法序列。CRF 的关键是特征工程——词性、前后缀、词典匹配、上下文窗口,特征设计得好效果就好。缺点是太依赖人工设计特征。BiLSTM-CRF:深度学习 NER 的经典架构。BiLSTM 自动学特征(不需要手工设计),CRF 层保证标签合法性。为什么需要 CRF?因为纯 BiLSTM 每个位置独立预测,可能出现"B-PER"后面跟"I-LOC"这种非法序列,CRF 通过学习转移矩阵约束标签之间的关系。BERT-CRF:用预训练的 BERT 替换 BiLSTM 作为编码器。BERT 自带丰富的语言知识,少量标注数据就能微调出好效果。在 CoNLL-2003 英文 NER 数据集上,BERT-CRF 的 F1 超过 92%,比 BiLSTM-CRF 高 3-5 个点。代价是推理速度慢、显存需求大。LLM 做 NER:GPT-4、Claude 可以通过 prompt 做 zero-shot NER,不需要训练数据。在通用实体上效果不错,但在专业领域(医疗、法律)和细粒度实体类型上还是微调模型更可靠。实际项目中,LLM 做 NER 的成本也比小模型高 10-100 倍。NER 的核心评估指标用精确率(Precision)、召回率(Recall)和 F1 值评估。NER 的"匹配"要求边界和类型都正确——"北京大学"标成 ORG 算对,标成 LOC 算错,只识别出"北京"也算错(边界不对)。实际项目中,精确率和召回率的取舍取决于业务:搜索引擎更重召回(别漏),法律合规更重精确(别标错)。中文 NER 的特殊挑战中文没有天然分词边界,"北京大学"可以是三个字也可以是一个实体。字级别的 NER(一个字一个字标注)比词级别更常见,因为避免了分词错误传播的问题——分词错了,NER 肯定跟着错。Lattice LSTM 就是专门解决这个问题的,它把分词信息作为额外路径融入字级别模型。
服务端阅读 06月1日 15:02

NLP 文本预处理有哪些步骤?LLM 时代还需要吗?

文本预处理是把原始文本变成模型能消化的输入的过程。传统 NLP 流程里这一步极其重要——垃圾进垃圾出,预处理做不好,模型再强也没用。但 LLM 时代有些变化,后面会说。预处理的核心步骤按顺序走:1. 清洗噪声:去掉 HTML 标签、URL、特殊符号、多余空格。爬虫抓的文本必做这步。用 BeautifulSoup 去 HTML 标签,正则去 URL(re.sub(r"http\S+", "", text)),没什么技术含量但很重要。2. 文本标准化:统一大小写(英文)、统一编码(UTF-8)、繁简转换(中文)。注意英文小写化会丢失一些信息——"US" 变成 "us" 就不是国家了。如果做 NER,这一步要慎重。3. 分词:把句子切成词或子词。英文按空格切就行(粗略说),中文必须用分词工具(jieba、pkuseg)。但更现代的做法是用子词分词(BPE、WordPiece),BERT 和 GPT 都用这种方式——它解决了 OOV(词表外词)问题,"unhappiness" 会被拆成 "un" + "happi" + "ness"。4. 去停用词:移除"的""了""is""the"这些高频但无实际含义的词。在搜索和分类任务中有用,但在情感分析中要小心——"not" 可能被去掉,语义就反了。LLM 时代这步基本不需要了,大模型自己能判断哪些词重要。5. 词形还原/词干提取:running → run,better → good。英文常用,中文不需要。NLTK 的 WordNetLemmatizer 做词形还原,PorterStemmer 做词干提取。词形还原更准确但更慢,词干提取更快但可能产出非词(如 "university" → "univers")。6. 序列填充/截断:神经网络需要固定长度的输入,长的截断,短的补 padding。BERT 最大 512 token,GPT-4 可以到 128K,但填充和截断的思路一样。LLM 时代,哪些预处理还需要?分词(tokenizer)仍然需要,但已经是模型自带的了——你不需要自己 jieba 分词再喂给 BERT,直接用模型的 tokenizer 就行。清洗噪声仍然需要——LLM 也不是什么垃圾都能消化,HTML 标签和乱码照样影响效果。去停用词、词形还原、词干提取基本不需要了。LLM 的上下文理解能力足以处理这些变化,手动去掉反而丢失信息。中文预处理的特殊问题中文没有天然的分隔符,分词质量直接影响下游任务。jieba 是最常用的工具,但准确率只有 90% 左右,专业领域(医学、法律)需要自定义词典。另一个常见问题是编码——GBK 和 UTF-8 混用的数据,Python 里先统一 encode("utf-8").decode("utf-8") 处理不了就加 errors 参数忽略。实操建议别一上来就全做。先看任务——情感分析去停用词要小心,文本生成不需要去,搜索需要去。先做最小预处理(清洗+分词),跑个 baseline,看效果再加步骤。预处理步骤越多,pipeline 越复杂,出错的地方也越多。
服务端阅读 06月1日 15:01

大语言模型(LLM)是什么?为什么它能做这么多事?

大语言模型(Large Language Model,LLM)是用海量文本训练的超大规模神经网络。它不是被编程去"做"某件事,而是通过预测下一个 token 学会了语言的规律——结果出乎意料地,这种能力泛化到了推理、翻译、写代码、做总结等各种任务上。LLM 和传统 NLP 模型有什么本质区别传统 NLP 是"一个模型做一件事"——分类模型做分类,NER 模型做实体识别,翻译模型做翻译。LLM 打破了这个限制:同一个模型,通过不同的提示词(prompt),就能完成几十种任务。这种能力叫涌现能力——模型小的时候没有,参数过了某个阈值突然就出现了。关键在于规模效应。GPT-3 有 1750 亿参数,训练数据覆盖了互联网上几乎所有的公开文本。当你给它一个 prompt,它不是在"查表"找答案,而是在学到的语言分布上做推理。这么说不太精确,但你可以理解为:它把训练数据里的模式压缩成了参数,然后根据 prompt 激活相关的模式来生成回答。核心技术:从 Transformer 到 RLHFLLM 的底层架构是 Transformer,2017 年 Google 在《Attention is All You Need》里提出。Transformer 的自注意力机制让模型能同时看到输入序列的所有位置,不需要像 RNN 那样逐步递归,训练时可以完全并行。但光有 Transformer 不够。从原始模型到好用的 ChatGPT,中间经历了三个关键步骤:预训练:在海量文本上做 next-token prediction,学会语言的基本规律。这步烧钱最多,GPT-4 的训练成本估计超过 1 亿美元。指令微调(SFT):用人工编写的指令-回答对微调,教模型"用户问问题你要这样答"。原始预训练模型只会续写,不会对话——SFT 让它变成了助手。RLHF:用人类偏好数据训练一个奖励模型,再用 PPO 算法优化语言模型。这一步让模型的回答更符合人类期望——更安全、更礼貌、更拒绝有害请求。LLM 能做什么理解和分析文本:读论文写摘要、从合同中提取关键条款、判断用户评论的情感倾向。这类任务 LLM 已经接近人类水平。生成内容:写邮件、写文案、写代码。代码生成是 LLM 落地最成功的场景之一——GitHub Copilot 用了 GPT 的代码能力,让开发者的编码效率提升了 30-50%。推理:链式思考(Chain-of-Thought)让 LLM 能做数学题、逻辑推理。2024 年 OpenAI 的 o1/o3 模型专门强化了推理能力,在数学和编程竞赛上接近人类顶尖水平。多模态:GPT-4V、Claude、Gemini 已经能看图、看视频、听语音。这不是简单的"图文拼接",而是模型真正理解了视觉内容和文字内容之间的语义关系。Agent:LLM 不只是回答问题,还能调用工具、执行任务、规划步骤。这是 2024-2025 最热的方向——让 LLM 成为能自主行动的智能体,而不是被动的问答机器。LLM 的局限幻觉(hallucination)是最头疼的问题——模型会自信地编造不存在的事实。上下文窗口有限(虽然已经从 4K 扩展到了 128K 甚至 1M),长文档处理仍有挑战。推理成本高,每次 API 调用都在烧钱。对小公司来说,部署自己的 LLM 仍然不现实——7B 模型需要至少 16GB 显存,70B 需要 4 张 A100。开源和闭源的格局闭源阵营:GPT-4o、Claude、Gemini 代表了最强性能。开源阵营:LLaMA(Meta)、Mistral、Qwen(阿里)、DeepSeek 追赶速度惊人。2025 年,开源 7B 模型的能力已经接近 GPT-3.5 水平,70B 模型在某些任务上和 GPT-4 打平。对开发者来说,开源模型意味着你可以私有化部署、定制微调、不用担心数据泄露。