Gradio全解系列——Additional Features:附加功能(上)

Gradio全解系列——Additional Features:附加功能(上)

  • 前言
  • 本篇摘要
  • 10. Additional Features:附加功能
    • 10.1 队列
      • 10.1.1 使用方法
      • 10.1.2 配置队列
    • 10.2 流输入输出
      • 10.2.1 流输出
        • 1. 生成器yield
        • 2. 流媒体
      • 10.2.2 流输入
        • 1. 流事件
        • 2. 图像滤镜
      • 10.2.3 统一的流输入输出
      • 10.2.4 跟踪过去的输入或输出
    • 10.3 提示及进度条
      • 10.3.1 提示
      • 10.3.2 进度条
    • 参考文献

前言

本系列文章主要介绍WEB界面工具Gradio。Gradio是Hugging Face发布的一个简易的webui开发框架,它基于FastAPI和svelte,便于部署人工智能相关模型,是当前热门的非常易于开发和展示机器学习大语言模型LLM及扩散模型DM的UI框架。本系列文章分为前置概念和实战演练两部分。前置概念先介绍Gradio的详细技术架构、历史、应用场景、与其他框架Gradio/NiceGui/StreamLit/Dash/PyWebIO的区别,然后详细介绍了大模型及数据的资源网站Hugging Face,包括三种资源models/datasets/spaces、六类开源库transformers/diffusers/datasets/PEFT/accelerate/optimum实战及Course课程资源。实战演练部分先讲解了多种不同的安装、运行和部署方式,安装包括Linux/Win/Mac三种安装方式,运行包括普通方式运行和热重载方式运行两种运行方式,部署包括本地部署、HuggingFace托管、FastAPI挂载和Gradio-Lite浏览器集成;然后按照先整体再细节的逻辑,讲解Gradio的多种高级特性:三种Gradio Clients(python/javascript/curl)、Gradio Tools等,方便读者对Gradio整体把握;最后深入细节,也是本系列文章的核心,实践基础功能Interface、Blocks和Additional Features,高级功能Chatbots、Data Science And Plots和Streaming。本系列文章注解详细,代码均可运行并附有大量运行截图,方便读者理解,Gradio一定会成为每个技术人员实现奇思妙想的最称手工具。

本系列文章目录如下:

  1. 《Gradio全解系列1——Gradio简介》
  2. 《Gradio全解系列1——Gradio的安装与运行》
  3. 《Gradio全解系列2——Gradio的3+1种部署方式实践》
  4. 《Gradio全解系列2——浏览器集成Gradio-Lite》
  5. 《Gradio全解系列3——Gradio Client:python客户端》
  6. 《Gradio全解系列3——Gradio Client:javascript客户端》
  7. 《Gradio全解系列3——Gradio Client:curl客户端》
  8. 《Gradio全解系列4——Gradio Tools:将Gradio用于LLM Agents》
  9. 《Gradio全解系列5——Gradio库的模块架构和环境变量》
  10. 《Gradio全解系列6——Interface:高级抽象界面类(上)》
  11. 《Gradio全解系列6——Interface:高级抽象界面类(下)》
  12. 《Gradio全解系列7——Blocks:底层区块类(上)》
  13. 《Gradio全解系列7——Blocks:底层区块类(下)》
  14. 《Gradio全解系列8——Additional Features:附加功能(上)》
  15. 《Gradio全解系列8——Additional Features:附加功能(下)》
  16. 《Gradio全解系列9——Chatbots:聊天机器人(上)》
  17. 《Gradio全解系列9——Chatbots:聊天机器人(下)》
  18. 《Gradio全解系列10——Data Science And Plots:数据科学与绘图》
  19. 《Gradio全解系列11——Streaming:数据流(上)》
  20. 《Gradio全解系列11——Streaming:数据流(下)》

本篇摘要

本篇介绍Gradio的附加功能,包括队列、出入数据流、提示信息及进度显示、批处理函数、安全访问文件和资源清理,下面逐一讲述。

10. Additional Features:附加功能

本章介绍Gradio的附加功能,包括队列、出入数据流、提示信息及进度显示、批处理函数、安全访问文件和资源清理,下面逐一讲述。

10.1 队列

每个Gradio程序提供了一个内置的队列系统,可以处理数千个并发用户。由于许多事件监听器可能涉及繁重的处理任务,Gradio 会自动为每个事件监听器创建一个队列来处理后端的事件,因此每个事件监听器都会自动拥有一个队列来处理传入的事件。

10.1.1 使用方法

如果函数推理时间较长,比如目标检测;或者应用程序处理流量过大,则需要使用queue方法进行排队。通过启用队列,可以控制用户在队列中的位置,queue方法使用websockets,可以防止网络超时。

队列使用方式如下:

demo = gr.Interface(...).queue()
demo.launch()
#或
with gr.Blocks() as demo:
    #...
demo.queue()
demo.launch()

以Blocks为例,演示如下:

with gr.Blocks() as demo:
    button = gr.Button(label="Generate Image")
    button.click(fn=image_generator, inputs=gr.Textbox(), outputs=gr.Image())
demo.queue(max_size=10)
demo.launch()

10.1.2 配置队列

默认情况下,每个事件监听器都有自己的队列,一次处理一个请求。可以通过事件监听器的两个参数进行配置:

  • concurrency_limit:设置事件监听器的最大并发执行数。默认情况下限制为 1,除非在 Blocks.queue() 中另行配置。你也可以将其设置为 None 以表示无限制(即无限数量的并发执行);
  • concurrency_id:允许事件监听器通过分配相同的 ID 来共享队列。当使用共享队列管理多个事件监听器时,使用concurrency_id指定队列,例如如果你的设置中只有 2 个 GPU,但多个函数需要 GPU 访问,你可以为所有这些函数创建一个共享队列。

示例如下:

import gradio as gr

with gr.Blocks() as demo:
    prompt = gr.Textbox()
    image = gr.Image()
    generate_btn_1 = gr.Button("Generate Image via model 1")
    generate_btn_2 = gr.Button("Generate Image via model 2")
    generate_btn_3 = gr.Button("Generate Image via model 3")
    generate_btn_1.click(image_gen_1, prompt, image, concurrency_limit=2, concurrency_id="gpu_queue")
    generate_btn_2.click(image_gen_2, prompt, image, concurrency_id="gpu_queue")
    generate_btn_3.click(image_gen_3, prompt, image, concurrency_id="gpu_queue")

在这个例子中,所有三个事件监听器共享一个标识为 “gpu_queue” 的队列。该队列最多可以同时处理 2 个并发请求,额外的请求将被排队,直到有可用的槽位。这些配置使得管理Gradio队列行为变得非常容易。
注意事项:

  1. 要确保事件监听器的并发无限制,可以将 concurrency_limit设置为None,这在你的函数调用外部 API(该API自行处理请求的速率限制)时非常有用。
  2. 所有队列的默认并发限制可以使用Blocks.queue()中的default_concurrency_limit参数全局设置。

10.2 流输入输出

10.2.1 流输出

在某些情况下,我们需要流式输出一系列结果,而不是一次性显示单个输出。例如,某个图像生成模型希望显示每一步生成的图像,直到最终图像生成;或者某个聊天机器人,它逐词流式输出响应,而不是一次性返回所有内容。在这种情况下,可以向 Gradio 提供一个生成器函数。

1. 生成器yield

在Python 中创建生成器非常简单:该函数不是返回单个值,而是生成一系列值。通常yield 语句会放在某种循环中,可以像提供常规函数一样向 Gradio 提供生成器。

例如,以下是一个模拟的图像生成模型,它在输出图像之前生成若干步噪声,使用 gr.Interface 类进行演示:

import gradio as gr
import numpy as np
import time

def fake_diffusion(steps):
    rng = np.random.default_rng()
    for i in range(steps):
        time.sleep(1)
        image = rng.random(size=(600, 600, 3))
        yield image
    image = np.ones((1000,1000,3), np.uint8)
    image[:] = [255, 124, 0]
    yield image

demo = gr.Interface(fake_diffusion,
                    inputs=gr.Slider(1, 10, 3, step=1),
                    outputs="image")

demo.launch()

运行截图如下:
在这里插入图片描述
请注意,我们在迭代器中添加了 time.sleep(1),它在步骤之间创建一个人为的暂停,这样就能够观察到迭代器的每一步(在真实的图像生成模型中,这可能是不必要的)。

同样,Gradio 可以处理流式输入,例如,每当用户在文本框中输入一个字母时,图像生成模型都会重新运行。这在关于构建响应式界面的中有更详细的介绍,请参考Interface章节中关于实时Interface的讲解。

2. 流媒体

Gradio 可以直接从生成器函数中流式传输音频和视频,这让用户几乎在函数生成音频或视频的同时就能听到或看到。实现流式媒体只需执行以下操作:

  1. 在 gr.Audio 或 gr.Video 输出组件中设置 streaming=True;
  2. 编写一个 Python 生成器,生成下一个音频或视频的“chunk”块;
  3. 设置 autoplay=True,以便媒体自动开始播放。

对于音频,下一个“块”可以是 .mp3 或 .wav 文件,也可以是音频的字节序列。对于视频,下一个“块”必须是 .mp4 文件或使用 h.264 编解码器且扩展名为 .ts 的文件。为了确保流畅播放,请确保每个块的长度一致且大于 1 秒。

我们将通过一些简单的示例来说明这些要点,以音频为例:

import gradio as gr
from time import sleep

def keep_repeating(audio_file):
    for _ in range(10):
        sleep(0.5)
        yield audio_file

gr.Interface(keep_repeating,
             gr.Audio(sources=["microphone"], type="filepath"),
             gr.Audio(streaming=True, autoplay=True)
).launch()

运行后点击submit,输出与输入同步播放,截图如下:
在这里插入图片描述
同样也可以视频为例,只需将gr.Audio替换为gr.Video即可:gr.Video(sources=["webcam"], format="mp4"),不再重复。关于流式的端到端示例请参考后续的数据流章节。

10.2.2 流输入

在上一小节中,我们介绍了如何从事件处理程序中流式输出一系列结果。Gradio还可以将用户摄像头中的图像或麦克风中的音频块流式传输到事件处理程序中,这可以用于创建实时对象检测应用程序或使用Gradio构建对话式聊天应用。

1. 流事件

目前,gr.Image 和 gr.Audio 组件支持通过 stream 事件实现流式输入传输。比如创建一个最简单的流式应用程序,直接返回未修改的网络摄像头流:

import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            input_img = gr.Image(label="Input", sources="webcam")
        with gr.Column():
            output_img = gr.Image(label="Output")
        input_img.stream(lambda s: s, input_img, output_img, time_limit=15, stream_every=0.1, concurrency_limit=30)

if __name__ == "__main__":
    demo.launch()

运行截图如下:
在这里插入图片描述
可以自己运行看一下效果。当用户开始录制时,stream 事件会被触发。底层逻辑是,网络摄像头每 0.1 秒拍摄一张照片并将其发送到服务器,然后服务器会返回该图像。

stream 事件有两个独特的关键字参数:

  • time_limit:这是 Gradio 服务器处理事件的时间限制。媒体流本质上是无限制的,因此设置时间限制非常重要,以防止一个用户长期占用 Gradio 队列。时间限制仅计算处理流所花费的时间,不包括在队列中等待的时间。输入图像底部显示的橙色条表示剩余时间。当时间限制到期时,用户将自动重新加入队列。
  • stream_every:这是流捕获输入并将其发送到服务器的频率(以秒为单位)。对于图像检测或处理等演示,设置较小的值可以实现“real-time”实时效果。对于语音转录等演示,较高的值更有用,因为可以使转录算法可以更好地理解上下文。
2. 图像滤镜

让我们创建一个滤镜演示,用户可以选择应用于其网络摄像头流的滤镜。用户可以选择边缘检测滤镜、卡通滤镜,或者简单地垂直翻转流。代码如下:

import gradio as gr
import numpy as np
import cv2

def transform_cv2(frame, transform):
    if transform == "cartoon":
        # prepare color
        img_color = cv2.pyrDown(cv2.pyrDown(frame))
        for _ in range(6):
            img_color = cv2.bilateralFilter(img_color, 9, 9, 7)
        img_color = cv2.pyrUp(cv2.pyrUp(img_color))

        # prepare edges
        img_edges = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
        img_edges = cv2.adaptiveThreshold(
            cv2.medianBlur(img_edges, 7),
            255,
            cv2.ADAPTIVE_THRESH_MEAN_C,
            cv2.THRESH_BINARY,
            9,
            2,
        )
        img_edges = cv2.cvtColor(img_edges, cv2.COLOR_GRAY2RGB)
        # combine color and edges
        img = cv2.bitwise_and(img_color, img_edges)
        return img
    elif transform == "edges":
        # perform edge detection
        img = cv2.cvtColor(cv2.Canny(frame, 100, 200), cv2.COLOR_GRAY2BGR)
        return img
    else:
        return np.flipud(frame)

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            transform = gr.Dropdown(choices=["cartoon", "edges", "flip"],
                                    value="flip", label="Transformation")
            input_img = gr.Image(sources=["webcam"], type="numpy")
        with gr.Column():
            output_img = gr.Image(streaming=True)
        dep = input_img.stream(transform_cv2, [input_img, transform], [output_img],
                                time_limit=30, stream_every=0.1, concurrency_limit=30)

demo.launch()

在这里插入图片描述

请注意,当更改滤镜值时,它会立即在输出流中生效。这是流事件与其他 Gradio 事件的一个重要区别:在处理流的过程中,可以更改流的输入值并立即生效。

提示:我们将图像输出组件的 streaming 参数设置为True,这样可以让服务器自动将输出图像转换为 base64 格式,这是一种适合流高效传输的格式。

10.2.3 统一的流输入输出

对于一些图像流式传输演示(如上面的示例),我们不需要分别显示输入和输出组件,只显示修改后的输出流,应用程序看起来会更简洁。

我们可以通过将输入图像组件指定为流事件的输出来实现这一点,省略重复代码,核心代码如下:

css=""".my-group {max-width: 500px !important; max-height: 500px !important;}
            .my-column {display: flex !important; justify-content: center !important; align-items: center !important};"""

with gr.Blocks(css=css) as demo:
    with gr.Column(elem_classes=["my-column"]):
        with gr.Group(elem_classes=["my-group"]):
            transform = gr.Dropdown(choices=["cartoon", "edges", "flip"],
                                    value="flip", label="Transformation")
            input_img = gr.Image(sources=["webcam"], type="numpy", streaming=True)
    input_img.stream(transform_cv2, [input_img, transform], [input_img], time_limit=30, stream_every=0.1)

demo.launch()

运行截图如下:
在这里插入图片描述

10.2.4 跟踪过去的输入或输出

通常流式函数应该是无状态的,它应该接受当前输入并返回相应的输出。然而在某些情况下,可能希望跟踪过去的输入或输出。例如可能希望在缓冲区保留前 k 个输入,以提高转录演示的准确性。可以使用 Gradio 的 gr.State()组件来实现这一点,示例如下:

def transcribe_handler(current_audio, state, transcript):
    next_text = transcribe(current_audio, history=state)
    state.append(current_audio)
    # 保留前3个输入
    state = state[-3:]
    return state, transcript + next_text

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            mic = gr.Audio(sources="microphone")
            state = gr.State(value=[])
        with gr.Column():
            transcript = gr.Textbox(label="Transcript")
    mic.stream(transcribe_handler, [mic, state, transcript], [state, transcript],
               time_limit=10, stream_every=1)

demo.launch()

10.3 提示及进度条

10.3.1 提示

提示组件分为三类:gr.Error()、 gr.Warning() 和gr.Info() 。我们希望向用户显示提示错误信息,为此可以在函数中抛出 gr.Error(“自定义消息”) ,这时函数停止执行并向用户显示错误信息。

我们还可以通过在函数中单独使用 gr.Warning(“自定义消息”) 或 gr.Info(“自定义消息”) 来立即显示模态框,同时继续执行函数。gr.Info() 和 gr.Warning() 之间的唯一区别是提示框的颜色。演示如下:

import gradio as gr
from functools import partial

with gr.Blocks() as demo:
    with gr.Row():
        duration = gr.Number(label="Duration", info="Set to -1 for infinite", value=10, minimum=-1)
    with gr.Row():
        error = gr.Button("Error")
        info = gr.Button("Info")
        warning = gr.Button("Warning")

    def display_message(type, msg, duration):
        duration = None if duration < 0 else duration
        if type == "error":
            raise gr.Error(msg, duration=duration)
        elif type == "info":
            gr.Info(msg, duration=duration)
        elif type == "warning":
            gr.Warning(msg,  duration=duration)

    error.click(partial(display_message, "error", "ERROR 💥"),  [duration])
    info.click(partial(display_message, "info", "INFO ℹ️"), [duration])
    warning.click(partial(display_message, "warning", "WARNING ⚠️"), [duration])

运行结果如下:
在这里插入图片描述
提示:请注意gr.Error()是一个必须引发的异常,而gr.Warning()gr.Info()是直接调用的函数。

10.3.2 进度条

Gradio 支持创建自定义进度条,可以自定义和控制进度更新,以便向用户展示。要启用此功能,只需在方法中添加一个参数,该参数的默认值为 gr.Progress 实例;然后通过直接调用此实例并传入一个介于 0 和 1 之间的浮点数来更新进度,或者使用 Progress 实例的 tqdm() 方法来跟踪可迭代对象的进度,如下所示:

import gradio as gr
import time

def slowly_reverse(word, progress=gr.Progress()):
    progress(0, desc="Starting")
    time.sleep(1)
    progress(0.05)
    new_string = ""
    for letter in progress.tqdm(word, desc="Reversing"):
        time.sleep(0.25)
        new_string = letter + new_string  
    return new_string

demo = gr.Interface(slowly_reverse, gr.Text(), gr.Text())
demo.launch()

运行截图如下:
在这里插入图片描述
如果使用 tqdm 库,甚至可以通过将gr.Progress()的参数track_tqdm设置为True,自动从任何函数中已存在的 tqdm.tqdm 报告进度更新!

参考文献

  1. Gradio - guides - Additional Features

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944196.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TestMAX/DFT Compiler:时序单元的类型、连接顺序和后DFT优化

相关阅读 TestMAX/DFT Compilerhttps://blog.csdn.net/weixin_45791458/category_12865937.html?spm1001.2014.3001.5482 时序单元的状态 未映射的时序单元(Unmapped Sequential Cell) 在Design Compiler读取了一个RTL设计后&#xff0c;Design Compiler内置的HDL Compiler工…

Cocos Creator 3.8.5 正式发布,更小更快更多平台!

在 Cocos Creator 3.8.5 版本中&#xff0c;我们做了新一轮的优化。 在加载速度、代码裁剪、平台增强等多方面做了优化&#xff0c;提升了开发者体验和游戏性能。 希望能够助 Cocos 开发者们的产品更上一层楼。 一、加载速度优化 1、WASM 模块延迟加载 在早期版本中&#xff0c…

跨语言数据格式标准化在 HarmonyOS 开发中的实践

文章目录 前言数据格式标准化的意义数据传递中的痛点标准化的优势 JSON 与 Protocol Buffers 的比较JSONProtocol Buffers HarmonyOS 跨语言数据传递示例示例代码&#xff1a;定义 Protocol Buffers 消息格式生成 Java 和 C 代码示例代码&#xff1a;Java 端序列化与传递数据C …

【有作图代码】多尺度动力学模型:像“显微镜与望远镜的结合”,揭示微观分子运动与宏观流体流动的奥秘

【有作图代码】多尺度动力学模型&#xff1a;像“显微镜与望远镜的结合”&#xff0c;揭示微观分子运动与宏观流体流动的奥秘 具体实例与推演 假设我们有一个流体系统&#xff0c;其中微观尺度上分子间的相互作用可以通过分子动力学方程描述&#xff0c;而宏观尺度上流体的流…

工具变量笔记

补充知识 简单介绍工具变量 假设 Y i α β D i ϵ i Y_i\alpha\beta D_i\epsilon_i Yi​αβDi​ϵi​, where E ( ϵ i ∣ D i ) 0 E(\epsilon_i\mid D_i)0 E(ϵi​∣Di​)0. 但是通常这个条件不满足。于是假如有这样一个工具变量 Z i Z_i Zi​存在的话&#xff0c;满…

通过 Ansys Electronics Desktop 中的高级仿真优化 IC 设计

半导体行业继续通过日益复杂的集成电路 (IC) 设计突破技术界限。随着工艺节点缩小和电路密度达到前所未有的水平&#xff0c;电磁效应对设备性能和可靠性变得越来越重要。现代 IC 设计面临着来自复杂的布局相关耦合机制、信号完整性问题和功率分布问题的挑战&#xff0c;这些问…

Yocto 项目中的交叉编译:原理与实例

Yocto 项目是一个强大的工具集&#xff0c;它专注于为嵌入式系统生成定制的 Linux 发行版。交叉编译在 Yocto 项目中扮演着核心角色&#xff0c;它使得开发者能够在功能强大的宿主机上构建适用于资源受限目标设备的软件系统。这篇文章将从运行原理、实际案例和工具链组成等角度…

WPF 绘制过顶点的圆滑曲线(样条,贝塞尔)

项目中要用到样条曲线&#xff0c;必须过顶点&#xff0c;圆滑后还不能太走样&#xff0c;捣鼓一番&#xff0c;发现里面颇有玄机&#xff0c;于是把我多方抄来改造的方法发出来&#xff0c;方便新手&#xff1a; 如上图&#xff0c;看代码吧&#xff1a; -------------------…

谷粒商城-高级篇-秒杀业务

1、后台添加秒杀商品 1、配置网关 - id: coupon_routeuri: lb://gulimall-couponpredicates:- Path/api/coupon/**filters:- RewritePath/api/(?<segment>.*),/$\{segment} 2、每日秒杀关联商品功能实现 点击关联商品后&#xff0c;应该查询当前场次的所有商品 点击关…

JuOne核心模块揭秘:从智能硬件到Web3生态的完美连接

JuOne核心模块揭秘&#xff1a;从智能硬件到Web3生态的完美连接在全球数字经济的浪潮中&#xff0c;Web3 正以前所未有的速度重塑我们的生活方式、商业模式和价值创造体系。它不仅仅是互联网的下一阶段&#xff0c;更是一场关于未来的革命。去中心化、用户主权、价值互联&#…

Kafka高性能设计

高性能设计概述 Kafka高性能是多方面协同的结果&#xff0c;包括集群架构、分布式存储、ISR数据同步及高效利用磁盘和操作系统特性等。主要体现在消息分区、顺序读写、页缓存、零拷贝、消息压缩和分批发送六个方面。 消息分区 存储不受单台服务器限制&#xff0c;能处理更多数据…

若依框架之简历pdf文档预览功能

一、前端 &#xff08;1&#xff09;安装插件vue-pdf&#xff1a;npm install vue-pdf &#xff08;2&#xff09;引入方式&#xff1a;import pdf from "vue-pdf"; &#xff08;3&#xff09;components注入方式&#xff1a;components:{pdf} &#xff08;4&…

【社区投稿】自动特征auto trait的扩散规则

自动特征auto trait的扩散规则 公式化地概括&#xff0c;auto trait marker trait derived trait。其中&#xff0c;等号右侧的marker与derived是在Rustonomicon书中的引入的概念&#xff0c;鲜见于Rust References。所以&#xff0c;若略感生僻&#xff0c;不奇怪。 marker …

Elasticsearch检索之三:官方推荐方案search_after检索实现(golang)

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一&#xff1a;使用fromsize实现分页 快速掌握Elasticsearch检索之二&#xff1a;滚动查询(scrool)获取全量数据(golang) 1、search_after检索 在前面的文章介绍了fromsize的普通分页…

精读DeepSeek v3技术文档的心得感悟

最近宋大宝同学读完了DeepSeekv3的文档&#xff0c;心中颇多感慨&#xff0c;忍不住想在这里记录一下对这款“业界有望启示未来低精度训练走向”的开源大模型的观察与思考。DeepSeek v3的亮点绝不仅仅是“Float8”或“超长上下文”这么简单&#xff0c;而是贯穿了从数值精度、注…

WAV文件双轨PCM格式详细说明及C语言解析示例

WAV文件双轨PCM格式详细说明及C语言解析示例 一、WAV文件双轨PCM格式详细说明1. WAV文件基本结构2. PCM编码方式3. 双轨PCM格式详细说明二、C语言解析WAV文件的代码示例代码说明一、WAV文件双轨PCM格式详细说明 WAV文件是一种用于存储未压缩音频数据的文件格式,广泛应用于音频…

Day1 微服务 单体架构、微服务架构、微服务拆分、服务远程调用、服务注册和发现Nacos、OpenFeign

目录 1.导入单体架构项目 1.1 安装mysql 1.2 后端 1.3 前端 2.微服务 2.1 单体架构 2.2 微服务 2.3 SpringCloud 3.微服务拆分 3.1 服务拆分原则 3.1.1 什么时候拆 3.1.2 怎么拆 3.2 拆分购物车、商品服务 3.2.1 商品服务 3.2.2 购物车服务 3.3 服务调用 3.3.1 RestTemplate 3.…

DeepSpeed 使用 LoRA 训练后文件结构详解

DeepSpeed 使用 LoRA 训练后文件结构详解 在大语言模型&#xff08;LLM&#xff09;的训练过程中&#xff0c;DeepSpeed 提供了强大的分布式训练能力&#xff0c;而 LoRA&#xff08;Low-Rank Adaptation&#xff09;通过参数高效微调技术显著减少了资源占用。完成训练后&…

Llama 3 预训练(二)

目录 3. 预训练 3.1 预训练数据 3.1.1 网络数据筛选 PII 和安全过滤 文本提取与清理 去重&#xff08;De-duplication&#xff09; 启发式过滤&#xff08;Heuristic Filtering&#xff09; 基于模型的质量过滤 代码和数学推理数据处理 多语言数据处理 3.1.2 确定数…

Autoware Universe 安装记录

前提&#xff1a; ubuntu20.04&#xff0c;英伟达显卡。 ROS2-Galactic安装 wget http://fishros.com/install -O fishros && . fishros 选择galactic(ROS2)版本&#xff0c;桌面版 ROS2-dev-tools安装 sudo apt install python3-testresources sudo apt update …