跳至主要内容

博文

目前显示的是 四月, 2025的博文

大语言模型的温度

在自然语言处理中,LLM(大语言模型)的“温度”(Temperature) 是一个控制生成文本随机性的超参数。它通过调整模型输出概率分布的平滑程度,直接影响生成结果的多样性和创造性。以下是详细解释: ---  核心作用   温度参数的数值范围通常大于0,具体效果如下: - 低温(如 0.1~0.5)     模型更倾向于选择概率最高的词,输出更保守、集中、连贯,但可能缺乏新意。     *示例:* 输入“天空是…”,生成“蓝色的”。   - 高温(如 1.0~1.5)     模型放松对高概率词的偏好,随机性增加,结果更不可预测甚至荒谬。     *示例:* 输入“天空是…”,生成“群青色的,仿佛被猫爪揉皱的丝绸”。   ---  技术原理   温度通过调整 softmax 函数中的 logits(未归一化的概率)来控制概率分布。   假设某个词的原始概率为 \( p_i \),调整后的概率为:   \ p_i' = \frac{\exp(\logits_i / T)}{\sum_j \exp(\logits_j / T)} \   其中 \( T \) 是温度:   - \( T \to 0 \):概率分布尖锐(仅最高概率词被选中,接近贪心搜索)。   - \( T \to \infty \):概率分布均匀(完全随机,类似抛硬币)。   ---  典型应用场景   1. 低温度(高确定性)      - 技术文档或问答任务(需准确性)。      - 翻译或摘要生成(避免跑题)。   2. 高温度(随机性)      - 写诗歌、故事(需要创意)。      - 生成多个备选答案(探索不同可能性)。   -...

langchain记忆和优化方案

在使用LangChain开发聊天机器人时,平衡上下文长度和历史记忆可通过以下策略实现,结合技术方法和LangChain工具: ---  1. 摘要压缩法(Summary Compression) - 实现方式:   - 使用`ConversationSummaryMemory`模块,自动生成历史对话的摘要。   - 在每轮对话后,用LLM生成简洁摘要(如“用户喜欢咖啡,曾询问订单状态”),替代原始长文本。 - 优点:显著减少token占用,保留核心信息。 - 示例代码:   python   from langchain.memory import ConversationSummaryMemory   from langchain.llms import OpenAI   llm = OpenAI()   memory = ConversationSummaryMemory(llm=llm)   memory.save_context({"input": "我喜欢喝咖啡"}, {"output": "已记录您的偏好"})   print(memory.load_memory_variables({})) 输出摘要 ---  2. 关键实体提取(Entity Extraction) - 实现方式:   - 使用`EntityMemory`模块,自动识别并存储用户、地点、偏好等实体。   - 结合数据库(如Redis)持久化存储关键信息。 - 优点:快速检索结构化数据,无需遍历历史。 - 示例代码:   python   from langchain.memory import EntityMemory   memory = EntityMemory(llm=llm)   memory.save_context({"input": "我叫张三"}, {"output": "你好,张三!"})   print(memory.load_memory_variables({"input": "我的名字是什么?"})) 返回"张三" ---  3. 滑...

基于IPv6的深度包检测和基于IPv4的深度包检测难度有什么区别

 ## 概述   IPv6 相较于 IPv4 在深度包检测(Deep Packet Inspection, DPI)上的难度主要体现在头部结构更复杂、分片机制更严格、原生安全特性更丰富,以及实现性能开销更大等方面。具体来说,IPv6 的扩展头(Extension Headers)设计虽然提高了协议的可扩展性与安全性,但也给 DPI 设备带来了多级头解析、状态重组与规则匹配复杂度提升的挑战;同时,源端分片与严格禁止路由过程中分片的机制,使得 DPI 在检测分片包时需要更完善的重组能力;再者,IPv6 原生支持 IPsec 与更大比例的加密流量,使得可见载荷进一步减少;最后,头部链解析与规则匹配对计算资源的消耗显著高于 IPv4,从而增加了硬件加速与软件优化的成本。   ## 1. 头部结构差异   IPv4 标准头部固定 20 字节,选项字段较少且大多只在特定场景使用;而 IPv6 基础头部即为 40 字节,且可紧随多个扩展头(如 Hop-by-Hop、Routing、Fragment 等)组成可变长度的“扩展头链”——这意味着 DPI 设备需按照 Next Header 字段依次解析每一级头部,才能定位实际的传输层或应用层数据,增加了多次内存访问和协议识别的复杂度 citeturn0search3。   另外,不同扩展头的处理规则彼此独立,部分扩展头(如 Routing Header)甚至可能携带跳跃路由信息,需要 DPI 设备额外解析并校验其合法性,进一步增大了实现难度 citeturn0search1。   ## 2. 分片机制差异   IPv4 允许中间路由器根据 MTU 重新分片,且分片头中带有所有传输层端口信息,DPI 设备可在任意路由节点上对分片包进行检测与重组;而 IPv6 仅允许源端主机在分片时添加 Fragment 扩展头,并且后续路由器必须将不符合 MTU 的整包丢弃,禁止路由器中途分片 citeturn0search7。这就要求 DPI 设备**在源端或边界路由处**完整重组所有分片,才能进行有效检测,否则无法获取完整负载;并且根据规范,IPv6 分片包在重组前的首个分片中可能缺少端口信息,DPI 需...

知识库技术选型:微调还是RAG

 在构建知识库问答系统时,选择大模型微调还是RAG技术需根据具体场景需求综合权衡。以下是两种技术的核心对比与适用性分析: --- ### **一、技术原理与核心差异** 1. **大模型微调(Fine-tuning)**      • **原理**:基于预训练大模型(如GPT、LLaMA等),通过特定领域的数据对模型参数进行二次训练,使其适应特定任务或知识体系。      • **优势**:        ◦ **高精度**:在稳定知识领域(如法律、医疗)表现更专业,回答符合领域规范。        ◦ **独立性**:无需依赖外部系统,推理速度快且上下文一致性高。      • **局限**:        ◦ **更新成本高**:需重新训练模型以适应知识库变更,耗时且计算资源消耗大。        ◦ **数据依赖**:需大量标注数据,否则易过拟合或泛化能力不足。 2. **RAG(检索增强生成)**      • **原理**:通过动态检索外部知识库(如向量数据库),将相关知识片段与大模型生成能力结合,增强回答的实时性与准确性。      • **优势**:        ◦ **实时性**:知识库更新后无需重新训练模型,直接通过检索获取最新信息。        ◦ **灵活性**:可处理大规模非结构化数据,支持多模态知识融合(文本、图像等)。      • **局限**:        ◦ **检索质量依赖**:若知识库索引不完善或噪声多,可能生成错误答案。        ◦ **生成延迟**:检索和生成流程增加系统复杂度...

Ubuntu linux修改dns服务器

在Ubuntu Linux系统中,修改DNS服务器分为临时和永久两种方式,具体方法如下: ---  一、临时修改DNS(重启后失效)  方法1:直接修改 `/etc/resolv.conf` bash sudo nano /etc/resolv.conf 删除原有 `nameserver` 行,添加新的DNS服务器: bash nameserver 8.8.8.8 nameserver 8.8.4.4 注意:如果系统使用 `systemd-resolved` 或 `NetworkManager`,此文件可能被自动覆盖,临时生效但重启后恢复。 ---  方法2:使用 `resolvectl` 命令(systemd-resolved) bash sudo resolvectl dns <网卡名> 8.8.8.8 8.8.4.4  示例(网卡名为enp0s3): sudo resolvectl dns enp0s3 8.8.8.8 8.8.4.4 ---  方法3:通过 `nmcli`(NetworkManager用户) bash sudo nmcli con mod <连接名> ipv4.dns "8.8.8.8 8.8.4.4" sudo nmcli con down <连接名> && sudo nmcli con up <连接名> ---  二、永久修改DNS  方法1:通过 Netplan(Ubuntu 18.04+ 默认) 1. 编辑Netplan配置文件(通常位于 `/etc/netplan/`): bash sudo nano /etc/netplan/01-netcfg.yaml 2. 在对应网卡下添加 `nameservers` 字段: yaml network:   version: 2   ethernets:     enp0s3:       dhcp4: true       nameservers:         addresses: 8.8.8.8, 8.8.4.4 3....

Go语言无名指针类型及其作用

  在 Go 语言中, 无名指针类型(Unnamed Pointer Type)   指的是直接通过指针语法(如   *int 、 *string )声明的指针类型,而不是通过   type   关键字显式命名的类型(如   type IntPtr *int )。它的核心作用是简化代码,提供底层类型的灵活性,避免不必要的类型转换。 无名指针类型的作用 隐式类型兼容性 无名指针类型直接基于底层类型,因此相同底层类型的指针可以直接赋值或传递,无需显式类型转换。 减少冗余代码 无需通过  type  定义新类型,直接使用  *T  语法,简化代码结构。 与标准库或第三方库兼容 许多库函数直接使用无名指针类型(如  *os.File ),使用无名类型可以无缝对接。 示例说明 场景 1:直接操作底层类型 go 复制 func main ( ) { a := 42 var ptr1 * int = & a // ptr1 是无名指针类型 *int fmt . Println ( * ptr1 ) // 输出 42 // 直接传递无名指针 modifyValue ( ptr1 ) fmt . Println ( * ptr1 ) // 输出 100 } func modifyValue ( p * int ) { * p = 100 } ptr1  是  *int  类型的无名指针,可以直接传递给接受  *int  参数的函数  modifyValue 。 场景 2:与命名指针类型的区别 go 复制 type NamedPtr * int // 命名指针类型 func main ( ) { x := 10 var p1 * int = & x // 无名指针类型 var p2 NamedPtr = & x // 命名指针类型 // p1 和 p2 的底层类型相同,但需要显式转换 p1 = ( * int...

PyTorch学习路线图

  第一阶段:基础知识(2-3周) 第1周:Python与机器学习基础 Python数据结构与NumPy基础 张量概念与线性代数基础 机器学习基本概念 第2-3周:PyTorch核心 张量操作与计算图 自动微分(autograd)机制 数据加载与预处理(DataLoader, Dataset) 构建神经网络模块(nn.Module) 第二阶段:深度学习基础(4-6周) 第4周:线性模型与优化器 线性回归与逻辑回归实现 优化器(SGD, Adam等) 损失函数与评估指标 第5-6周:基础神经网络 多层感知机(MLP) 卷积神经网络(CNN) 循环神经网络(RNN, LSTM, GRU) 第7-8周:训练技巧 模型保存与加载 学习率调度 正则化技术 迁移学习 第三阶段:进阶应用(6-8周) 第9-10周:计算机视觉 图像分类 目标检测 图像分割 视觉Transformer 第11-12周:自然语言处理 词嵌入 序列到序列模型 Transformer架构 预训练语言模型应用 第13-14周:生成模型 自编码器 变分自编码器(VAE) 生成对抗网络(GAN) 扩散模型 第四阶段:工程实践(4-6周) 第15-16周:模型部署 模型量化与优化 TorchScript与ONNX导出 服务化部署 移动端部署 第17-18周:高级训练技术 分布式训练 混合精度训练 梯度累积与梯度裁剪 模型剪枝与蒸馏 第19-20周:项目实战 完整项目流程 模型性能优化 工业级代码实践

new和make的用法及len和cap的用法

  一、内存分配函数对比 1.  new(Type) go 复制 ptr := new ( int ) // 返回 *int 指针 * ptr = 10 特点 : 分配零值内存,返回指针 适用于所有类型(包括基本类型和复合类型) 对复合类型不初始化底层结构(如  new([]int)  会创建  *[]int  指向 nil 切片) 2.  make(Type, len, cap) go 复制 s := make ( [ ] int , 3 , 5 ) // 长度3,容量5的切片 m := make ( map [ string ] int ) // 需省略cap参数 ch := make ( chan int , 5 ) // 缓冲通道容量5 特点 : 仅用于  slice / map / channel  的初始化 分配内存并初始化底层数据结构(如切片的指针数组、哈希表桶等) map  初始化时  cap  参数会被忽略(建议省略) 二、容量与长度函数 1.  cap()  适用类型 类型 含义 示例 array 等于数组长度(编译时确定) cap([3]int{})  → 3 slice 底层数组最大可扩展长度 cap(make([]int,2,5))  → 5 channel 缓冲区容量(非元素数量) cap(make(chan int,5))  →5 2.  len()  适用类型 类型 含义 示例 array 元素数量(编译时确定) len([3]int{})  → 3 slice 当前存储元素数量 len(make([]int,2,5))  → 2 channel 缓冲区中待读取元素数量 ch <- 1; len(ch)  →1 string 字节数(非字符数) len("中文")  →6 map 键值对数量 len(map[int]bool{1:true}) →1 三、核心类型特性 1. 数组 (Array) go 复制 var arr [ 3 ] int // 长度和容量固定为...

Go语言中的init函数

  1. init函数的作用 包初始化 : init 函数用于在包被导入时执行初始化任务(如配置资源、注册组件等)。 可重复定义 :同一个包中可以定义多个 init 函数,它们会按顺序执行。 2. init函数的执行顺序 (1)同一个Go文件中的多个init函数 按代码中的 定义顺序 执行。 go 复制 // a.go 文件内 func init ( ) { fmt . Println ( "init 1" ) } func init ( ) { fmt . Println ( "init 2" ) } // 输出:init 1 → init 2 (2)同一个包中的不同文件 按 文件名排序 (字典序)执行各文件中的 init 。 例如: a.go 的 init 先于 b.go 的 init 执行。 (3)不同包的init函数 按 依赖关系 从最深到最浅执行: 被导入的包 的 init 优先于 当前包 的 init 。 若包A导入包B,包B导入包C,则执行顺序为:C → B → A。 同一层级按 import 语句的 顺序 执行。 3. Go程序的完整初始化顺序 被导入的包 : 递归初始化其依赖的包。 初始化包级变量和常量。 执行包的 init 函数。 当前包 : 初始化包级变量和常量。 执行当前包的 init 函数。 main函数 : 最后执行 main 包的 main 函数。 正确顺序总结 : text 复制 被导入包的变量/常量 → 被导入包的init → 当前包的变量/常量 → 当前包的init → main函数 4. 其他关键规则 (1)init函数的唯一性 即使一个包被多次导入(如多个包依赖它),其 init 函数 仅执行一次 (包级单例)。 (2)执行环境 所有 init 函数在同一个 goroutine 中按顺序执行,不存在并发问题。 (3)避免循环导入 Go禁止循环导入(如包A导入包B,包B又导入包A),需通过设计解耦。 示例代码验证 场景 : 包 deep (依赖层次最深) → 包 middle  → 包 main 。 go 复制 // deep/init.go package deep func init ( ) { fmt . Println ( "deep in...