news 2026/2/7 18:43:12

Serilog 日志库简单实践(一):文件系统 Sinks(.net8)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Serilog 日志库简单实践(一):文件系统 Sinks(.net8)

从本文开始,后续将对各种类型的 Sinks 进行简单的实践。

本文将以文件系统相关的 Sinks 为主进行介绍,针对多个相关的动态库,进行了简介以及示例项目实现,供参考。

回到顶部

一、文件系统 Sinks 用法

1.1 Serilog.Sinks.File:最基础的日志组件

Serilog.Sinks.File 是 Serilog 社区维护的核心文件日志接收器,用于将日志事件写入到一个或多个文本文件中。

它支持文本和 JSON 格式输出,保留结构化数据,是 Serilog 生态中最基础的文件日志组件。也支持按时间(如每天、每周)或大小滚动日志文件,可配置多进程共享日志文件,支持写入缓冲以提高性能。

如下是简单实践,可以简单分为四步:

1)创建 .NET 8 Web API 项目,并安装 NuGet 包:

dotnet add package Serilog.AspNetCore

dotnet add package Serilog.Sinks.File

// dotnet sdd package Serilog.Enrichers.Environment // 有需求要添加机器名时,需要添加此包

// dotnet sdd package Swashbuckle.AspNetCore // 若需要使用 Swagger 时,需添加此包

// 注意:使用 Serilog.AspNetCore 而不是基础的 Serilog,

// 因为它为 ASP.NET Core 提供了更好的集成(如自动记录请求、依赖注入支持等)

2)添加 appsettings.json 配置(非必要)。

虽然当前示例项目中,主要在代码中配置 Serilog,但也可以将部分设置放在 appsettings.json 中。

例如:

{

"Serilog": { // 根节点

"MinimumLevel": { // 定义了日志记录的最低级别,只有等于或高于此级别的日志才会被记录下来

"Default": "Debug", // 全局默认的日志最低级别是 Debug

"Override": { // 为特定命名空间或类库重写默认的日志级别

"Microsoft": "Warning", // 所有来自 Microsoft 命名空间(例如框架内部代码)的日志,只记录 Warning 及以上级别(即 Warning, Error, Fatal)

"Microsoft.AspNetCore": "Warning" // Microsoft.AspNetCore 相关组件(如 MVC、HTTP 请求管道等)也只记录 Warning 及以上级别

}

}

},

"AllowedHosts": "*" // 用于控制应用响应哪些 HTTP 主机头(Host header)的请求,"*" 表示允许所有主机访问

// 在开发环境下通常设为 "*",但在生产环境中建议明确指定受信任的主机以增强安全性

}

当全局默认的日志最低级别是 Debug 时,应用程序中所有代码(除非特别覆盖)产生的 Debug、Information、Warning、Error、Fatal 级别的日志都会被记录。

日志级别从低到高通常是:Verbose < Debug < Information < Warning < Error < Fatal。

ASP.NET Core 框架本身会产生大量关于Microsoft、Microsoft.AspNetCore 两个命名空间的 Information 和 Debug 级别的日志,如果不加限制,在生产环境中会非常冗长且影响性能。通过将其级别提高到 Warning,可以减少噪音日志,只关注真正重要的信息。

3)修改 Program.cs(核心配置)

using Microsoft.AspNetCore.Builder;

using Serilog;

using Serilog.Formatting.Json;

var builder = WebApplication.CreateBuilder(args);

Log.Logger = new LoggerConfiguration()

.ReadFrom.Configuration(builder.Configuration) // 读取 appsettings.json 中的 Serilog 配置

.Enrich.FromLogContext() // 启用上下文(如 BeginScope)

.Enrich.WithMachineName() // 添加机器名 // 需要包:Serilog.Enrichers.Environment

.Enrich.WithEnvironmentUserName() // 添加用户名

.WriteTo.Console(new JsonFormatter()) // 控制台也输出 JSON(可选,便于开发)

.WriteTo.File(

path: "logs/api-.log",

// formatter: new JsonFormatter(), // 关键:使用 JSON 格式保留结构化数据

formatter: new JsonFormatter(renderMessage: true), // renderMessage 加上此选项,日志中才会输出"RenderedMessage"

rollingInterval: RollingInterval.Day, // 按天滚动

fileSizeLimitBytes: 10_000_000, // 单文件最大 10MB

retainedFileCountLimit: 31, // 最多保留 31 天

rollOnFileSizeLimit: true, // 达到大小限制时也滚动

shared: true // 允许多个进程写入(IIS/容器场景需要)

)

.CreateLogger();

// 告诉 ASP.NET Core 使用 Serilog 作为日志提供者

builder.Host.UseSerilog();

// Add services to the container.

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen(); // 要使用 Swagger 需要添加包:Swashbuckle.AspNetCore

var app = builder.Build();

// 配置 HTTP 请求管道

if (app.Environment.IsDevelopment())

{

app.UseSwagger();

app.UseSwaggerUI();

}

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

// 在应用启动时记录一条结构化日志

app.Lifetime.ApplicationStarted.Register(() =>

{

Log.Information("Application started. Environment: {Environment}, ContentRoot: {ContentRoot}",

app.Environment.EnvironmentName,

app.Environment.ContentRootPath);

});

// 在应用停止时记录

app.Lifetime.ApplicationStopping.Register(() =>

{

Log.Information("Application is stopping.");

});

app.Run();

4)修改 WeatherForecastController.cs

using Microsoft.AspNetCore.Mvc;

namespace Test.WebAPI._8._0.Serilog.WriteToFile.Controllers

{

[ApiController]

[Route("[controller]")]

public class WeatherForecastController : ControllerBase

{

private static readonly string[] Summaries = new[]

{

"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"

};

private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)

{

_logger = logger;

}

[HttpGet]

public IEnumerable<WeatherForecast> Get()

{

// 记录结构化日志

_logger.LogInformation("Fetching weather forecasts for user {UserId} from IP {ClientIp}",

HttpContext.User.Identity?.Name ?? "Anonymous",

HttpContext.Connection.RemoteIpAddress?.ToString());

try

{

var rng = new Random();

var forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast

{

Date = DateTime.Now.AddDays(index),

TemperatureC = rng.Next(-20, 55),

Summary = Summaries[rng.Next(Summaries.Length)]

}).ToArray();

// 记录复杂对象(使用 @ 解构)

_logger.LogDebug("Generated {ForecastCount} forecasts: {@Forecasts}",

forecasts.Length, forecasts);

return forecasts;

}

catch (Exception ex)

{

// 记录异常和上下文

_logger.LogError(ex, "An error occurred while generating weather forecasts for user {UserId}",

HttpContext.User.Identity?.Name ?? "Anonymous");

throw;

}

}

}

public class WeatherForecast

{

public DateTime Date { get; set; }

public int TemperatureC { get; set; }

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

public string? Summary { get; set; }

}

}

输出结果:

注:实际输出为默认的 json 字符串,如下是格式化后便于查看。

{

"Timestamp": "2025-10-23T23:30:44.9346095+08:00",

"Level": "Information",

"MessageTemplate": "Fetching weather forecasts for user {UserId} from IP {ClientIp}",

"RenderedMessage": "Fetching weather forecasts for user \"Anonymous\" from IP \"::1\"", // formatter: new JsonFormatter(renderMessage: true),配置效果

"TraceId": "8168e507fe989ade0dd4887075e3535e",

"SpanId": "9c78435a71c11ee6",

"Properties": {

"UserId": "Anonymous",

"ClientIp": "::1",

"SourceContext": "Test.WebAPI._8._0.Serilog.WriteToFile.Controllers.WeatherForecastController",

"ActionId": "15cb902a-b7c7-4b58-98e4-745dffec67e9",

"ActionName": "Test.WebAPI._8._0.Serilog.WriteToFile.Controllers.WeatherForecastController.Get (Test.WebAPI.8.0.Serilog.WriteToFile)",

"RequestId": "0HNGI94H06F88:00000001",

"RequestPath": "/weatherforecast",

"ConnectionId": "0HNGI94H06F88",

"MachineName": "WIN-J",

"EnvironmentUserName": "WIN-J\\Administrator"

}

}

1.2 Serilog.Sinks.Async:异步操作来避免主程阻塞

Serilog.Sinks.Async 不是一个独立的 Sink,而是一个异步包装器,用于将任何其他同步的 Sink(如 Serilog.Sinks.File)包装在异步操作中,减少日志记录对主线程的阻塞(特别是 Web 请求线程)。

在高并发场景下,如果日志直接写入文件、数据库或网络服务,这些 I/O 操作是同步阻塞的。如果在每个请求中都记录日志,会拖慢响应速度,甚至影响吞吐量。

Serilog.Sinks.Async 将日志记录工作委托给后台线程,减少 I/O 瓶颈对应用性能的影响,特别适用于文件和数据库等受 I/O 瓶颈影响的接收器。

工作原理

当程序调用 Log.Information() 时,日志事件被推入一个内部的异步队列(默认大小是 1000 条)之后,立马返回。一个后台线程(或线程池任务)从队列中取出日志,再交给被包装的 Sink(如 File Sink)处理。主线程无需等待写入完成,立即返回。

另外需要注意,极端情况下可能丢失最后几条日志(程序崩溃时),需要合理配置队列大小和溢出策略。

示例项目

大概思路:分别生成两个.net8.0 WebAPI 项目,一个使用同步,一个使用异步来实现将同样的内容,以 json 字符串的格式写入到文本文件中。启动服务后,通过压测工具(本文使用:wrk)观察性能差异。

下边是实际操作的简要步骤:

1.2.1 创建两个 .net 8.0 WebAPI 示例项目,然后添加几个动态库

同步项目名称:Test.WebAPI.8.0.Serilog.WriteToFile。异步实现项目:Test.WebAPI.Net8.Serilog.FileAsync。

需要引用的动态库:

// 两个项目都需要添加下边三个包:

dotnet add package Serilog.AspNetCore

dotnet add package Serilog.Sinks.File

dotnet add package Serilog.Formatting.Compact

// 异步实现另外添加 Async 专用包:

dotnet add package Serilog.Sinks.Async

1.2.2 编辑 Program.cs

同步项目实现:

using Serilog;

using Serilog.Events;

using Serilog.Formatting.Compact;

var builder = WebApplication.CreateBuilder(args);

// 【配置 Serilog(同步)】

builder.Host.UseSerilog((context, config) =>

{

config.WriteTo.File(

path: "logs-sync/log-.txt",

rollingInterval: RollingInterval.Day,

retainedFileCountLimit: 30,

// formatProvider: CultureInfo.InvariantCulture,

// outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",

formatter: new RenderedCompactJsonFormatter(), // 配置使用json格式字符串输出

restrictedToMinimumLevel: LogEventLevel.Information

);

});

var app = builder.Build();

app.MapGet("/api/logSync", () =>

{

Log.Information("Fetching weather forecasts for user {UserId} from IP {ClientIp}",

"Anonymous",

"This is IP");

return "Log recorded (synchronous)";

});

app.Run();

异步项目实现:

using Serilog;

using Serilog.Events;

using Serilog.Formatting.Compact;

var builder = WebApplication.CreateBuilder(args);

// 【配置 Serilog(异步)】

builder.Host.UseSerilog((context, config) =>

{

config.WriteTo.Async(a => a.File(

path: "logs-async/log-.txt",

rollingInterval: RollingInterval.Day,

retainedFileCountLimit: 30,

//formatProvider: CultureInfo.InvariantCulture,

//outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",

formatter: new RenderedCompactJsonFormatter(), // 配置使用json格式字符串输出

restrictedToMinimumLevel: LogEventLevel.Information

));

});

var app = builder.Build();

app.MapGet("/api/logAsync", () =>

{

Log.Information("Fetching weather forecasts for user {UserId} from IP {ClientIp}",

"Anonymous",

"This is IP");

return "Log recorded (asynchronous)";

});

app.Run();

配置完成,同时启动两个项目,两个服务地址例如:

// 服务地址:

http://localhost:5043/api/logSync

http://localhost:5001/api/logAsync

注:日志文件夹会在项目启动时自动创建,无需手动配置或新增。

1.2.3 测试与解析

直接在 Windows 上通过 Docker 和 wrk 来进行的是两种方式的性能差异。

// 安装和配置 Docker Desktop 步骤【略。。。】

// 博主使用的镜像源地址:"https://docker.xuanyuan.me",也可以使用阿里和腾讯的,哪个效率高用哪个

// 拉取 wrk 包

C:\Users\Administrator>docker pull williamyeh/wrk

Using default tag: latest

latest: Pulling from williamyeh/wrk

4fe2ade4980c: Pull complete

c4d7e348633d: Pull complete

3e403d3ebdda: Pull complete

bdb672ee55d9: Pull complete

2bfb714176a4: Pull complete

Digest: sha256:78adc0d9d51a99e6759e702a08d03eaece81c890ffcc9790ef9e5b199d54f091

Status: Downloaded newer image for williamyeh/wrk:latest

docker.io/williamyeh/wrk:latest

// 异步记录日志测试

// 注意:host.docker.internal 是 Docker 宿主机的特殊 DNS 名称,说明被测服务运行在宿主机上,而 wrk 在容器内发起请求

C:\Users\Administrator>docker run -it --rm williamyeh/wrk -t12 -c100 -d10s http://host.docker.internal:5001/api/logAsync

Running 10s test @ http://host.docker.internal:5001/api/logAsync

12 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 15.59ms 5.85ms 103.93ms 93.31%

Req/Sec 524.79 106.91 660.00 78.36%

63040 requests in 10.01s, 10.82MB read

Requests/sec: 6296.32

Transfer/sec: 1.08MB

// 同步记录日志测试

C:\Users\Administrator>docker run -it --rm williamyeh/wrk -t12 -c100 -d10s http://host.docker.internal:5043/api/logSync

Running 10s test @ http://host.docker.internal:5043/api/logSync

12 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 19.52ms 6.70ms 90.80ms 79.40%

Req/Sec 413.05 43.31 656.00 85.56%

49576 requests in 10.05s, 8.46MB read

Requests/sec: 4930.52

Transfer/sec: 862.05KB

C:\Users\Administrator>

// 关于 wrk -t12 -c100 -d10s

// 同时开启 12 个线程,每个线程与目标服务创建 100 个 TCP/HTTP keep-alive 连接,持续发起请求,持续 10 秒钟

// 相当于,在同一时间,有 1200 个连接在持续请求(一个请求完成,接着继续发出下一个请求)目标服务

下边简单分析下测试结果。

指标 异步 (/logAsync) 同步 (/logSync) 对比

总请求数 63,040 49,576 +27.1% ↑

吞吐量 (Requests/sec) 6,296.32 4,930.52 +27.7% 提升

传输速率 (Transfer/sec) 1.08 MB 862.05 KB +25.3% ↑

平均延迟 (Latency Avg) 15.59ms 19.52ms 快 20%

最大延迟 (Max Latency) 103.93ms 90.80ms 略高(可能因队列堆积)

延迟标准差 (Stdev) 5.85ms 6.70ms 更稳定

每秒请求数波动 (Req/Sec Stdev) ±106.91 ±43.31 异步波动更大,但均值更高

其中,异步操作的最大延迟稍高。可能原因:异步任务积压在线程池或消息队列中,在高峰期出现短暂排队,导致个别请求的“真实完成时间”变长(但从 API 返回角度看仍是快的)。

异步虽然吞吐高,但单位时间内请求处理数量波动更大,可能是由于线程调度、异步任务调度引入了不确定性。

总结一下,就是异步显著优于同步(+27% QPS,-20% 延迟)。

1.3 Serilog.Sinks.RollingFile:已过时,无需单独使用

此动态库主要功能是,配置日志文件如何按规则滚动,但现在已经在 Serilog.Sink.File 中进行了实现(详见本文1.1),因此无需再使用此动态库。

这个变化是 Serilog 在 2.0 版本之后(特别是向 3.0 和 5.0 进化过程中)的一个重要的演变。

但是,RollingFile 的功能并没有消失,而是被整合并增强到了 Serilog.Sinks.File 包中。现在推荐的做法是:只安装 Serilog.Sinks.File 这一个包,它就能满足所有文件输出需求,包括强大的滚动功能。

Serilog.Sinks.File 的 File() 方法提供了以下关键参数来实现滚动:

rollingInterval:这是最主要的滚动策略参数。它是一个 RollingInterval 枚举,可选值包括:

RollingInterval.Year:按年滚动。

RollingInterval.Month:按月滚动。

RollingInterval.Day:最常用,按天滚动。

RollingInterval.Hour:按小时滚动。

RollingInterval.Minute:按分钟滚动(适用于极高日志量的场景)。

RollingInterval.Infinite:不滚动,所有日志写入单个文件。(注意:Infinite 在 Serilog 5.0 中以被移除,如需配置不滚动,可以通过略过此项配置来实现)。

rollOnFileSizeLimit:一个布尔值。如果设置为 true,并且设置了 fileSizeLimitBytes,那么当日志文件达到指定大小时,也会触发滚动,即使当前时间间隔(如一天)还未结束。这实现了“按大小或时间”任一条件满足即滚动的逻辑。

fileSizeLimitBytes:设置单个日志文件的最大字节数。达到此大小后,如果 rollOnFileSizeLimit 为 true,则会创建新文件。

文件名中的 {Date} 占位符:当使用 rollingInterval 时,通常在文件路径中包含 {Date}。Serilog 会自动用当前日期(格式为 yyyyMMdd)替换它,从而生成如 log-20251026.txt 的文件名。

1.4 Serilog.Sinks.Map:根据日志属性的值将日志时间路由到不同的 Sink

Map 允许根据日志属性的值将日志事件路由到不同的 Sink。例如,可以根据 UserId 将日志写入不同的文件,非常适合需要按用户或租户隔离日志的场景。

因此,如果需要根据不同上下文(如用户ID、请求ID、租户ID等)将日志分发到不同的目标文件或处理逻辑,Map 是非常有用的;否则,一般不需要。

需要注意的地方:

性能开销:Map 内部使用字典缓存子 logger,频繁变化的键可能导致内存增长。

过度设计风险:大多数场景下,统一结构化日志 + 集中式日志分析工具(如 Seq、ELK)更合适。

Json 写入本身不需要 Map:你完全可以用 WriteTo.File(..., formatter: new JsonFormatter()) 直接输出 JSON 日志。

典型应用场景就是,按 UserId 将审计日志写入不同日志文件。

1.4.1 创建测试项目并添加必要的包

// 添加下边三个包:

dotnet add package Serilog.AspNetCore

dotnet add package Serilog.Sinks.File

dotnet add package Serilog.Sink.Map

1.4.2 修改 Program.cs

using Serilog;

using Serilog.Context;

using Serilog.Formatting.Compact;

using Serilog.Formatting.Json;

var builder = WebApplication.CreateBuilder(args);

// 配置 Serilog

Log.Logger = new LoggerConfiguration()

.Enrich.FromLogContext()

.MinimumLevel.Information()

// 主日志:所有日志汇总到一个 JSON 文件

.WriteTo.File(

new JsonFormatter(),

"logs/app-all-.json",

rollingInterval: RollingInterval.Day

)

// 特殊需求:按 UserId 分别记录审计日志到独立 JSON 文件

.WriteTo.Map("UserId", "unknown", (id, wt) =>

{

wt.File(

path: $"logs/audit/user_{id}-.json",

formatter: new RenderedCompactJsonFormatter(), // 输出为 JSON 格式

rollingInterval: RollingInterval.Day,

fileSizeLimitBytes: 10_000_000,

rollOnFileSizeLimit: true

);

})

.CreateLogger();

builder.Host.UseSerilog(); // 使用 Serilog 替代默认日志

var app = builder.Build();

// 模拟 API:记录带 UserId 的审计日志

app.MapGet("/api/user/{id}/action", (int id, ILogger<Program> logger) =>

{

using (LogContext.PushProperty("UserId", id)) // 设置上下文属性

{

Log.Information("User performed an action {id}", id);

Log.Information("User viewed profile {TestParameters}", "测试字符串");

}

// 也可以直接记录

Log.ForContext("UserId", id).Information("Another action logged.");

return Results.Ok(new { Message = "Action logged", UserId = id });

});

app.Run();

1.4.3 测试结果验证

// 如下是两个测试地址,分别是用户 1001 和 1002

http://localhost:5001/api/user/1001/action

http://localhost:5001/api/user/1002/action

注意,实际记录的 json 格式日志是没有格式化的,下面展示下格式化后的 json,仅为了方便查看。

如下是 \logs\audit\user_1001-20251031.json 文件内容:

{

"@t": "2025-10-31T09:20:18.5714393Z",

"@m": "User performed an action 1001",

"@i": "0c7b7f7a",

"@tr": "b93dc8db0938aac572cf3d92d437deaf",

"@sp": "baa1c0bc7eb6880f",

"id": 1001,

"UserId": 1001,

"RequestId": "0HNGOBQMLDQHE:00000001",

"RequestPath": "/api/user/1001/action",

"ConnectionId": "0HNGOBQMLDQHE"

}

{

"@t": "2025-10-31T09:20:18.5783697Z",

"@m": "User viewed profile \"测试字符串\"",

"@i": "acc2ba35",

"@tr": "b93dc8db0938aac572cf3d92d437deaf",

"@sp": "baa1c0bc7eb6880f",

"TestParameters": "测试字符串",

"UserId": 1001,

"RequestId": "0HNGOBQMLDQHE:00000001",

"RequestPath": "/api/user/1001/action",

"ConnectionId": "0HNGOBQMLDQHE"

}

{

"@t": "2025-10-31T09:20:18.5794363Z",

"@m": "Another action logged.",

"@i": "58648cce",

"@tr": "b93dc8db0938aac572cf3d92d437deaf",

"@sp": "baa1c0bc7eb6880f",

"UserId": 1001,

"RequestId": "0HNGOBQMLDQHE:00000001",

"RequestPath": "/api/user/1001/action",

"ConnectionId": "0HNGOBQMLDQHE"

}

另外两个日志文件内容就略过了:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/2 7:12:50

Wi-Fi CERTIFIED Multimedia™ (WMM®) 技术概述

1.0 概述 本文档定义了 WMM 的规范,WMM 是基于 IEEE 802.11e 标准补充 [2] 的 802.11 QoS 实现方案。最初提出 WMM 是为了防止因多个不兼容的 802.11e 预标准子集出现而导致的碎片化问题;部署 WMM 将为 802.11 语音、流媒体等服务提供可用的 QoS 功能。 1.1 参考文献 [1] …

作者头像 李华
网站建设 2026/2/6 11:04:05

Astrofy:快速构建现代化个人作品集的免费开源模板

Astrofy&#xff1a;快速构建现代化个人作品集的免费开源模板 【免费下载链接】astrofy Astrofy is a free and open-source template for your Personal Portfolio Website built with Astro and TailwindCSS. Create in minutes a website with Blog, CV, Project Section, S…

作者头像 李华
网站建设 2026/2/6 20:13:48

Opus 音频编解码器深度技术报告:架构原理、传输机制与演进分析

Opus 音频编解码器深度技术报告&#xff1a;架构原理、传输机制与演进分析 1. 引言&#xff1a;音频编码的统一范式 在数字音频处理的历史长河中&#xff0c;音频编码技术长期以来被划分为两个截然不同的阵营&#xff1a;语音编码与通用音频编码。这种二元分化源于应用场景的…

作者头像 李华
网站建设 2026/2/4 10:31:47

Python实现微信域名深度学习驱动的智能对抗性防御与流量伪装系统

Python实现微信域名深度学习驱动的智能对抗性防御与流量伪装系统功能概述本系统实现了一个基于深度强化学习、生成对抗网络和元学习的智能微信域名对抗防御系统。通过多模态特征学习、对抗性流量生成、智能策略优化和联邦学习框架&#xff0c;构建了一个能够持续学习和适应微信…

作者头像 李华
网站建设 2026/2/3 6:27:30

TVM量化部署实践:从模型压缩到CUDA加速的工程化方案

TVM量化部署实践&#xff1a;从模型压缩到CUDA加速的工程化方案 【免费下载链接】tvm-cn TVM Documentation in Chinese Simplified / TVM 中文文档 项目地址: https://gitcode.com/gh_mirrors/tv/tvm-cn 挑战&#xff1a;如何在保持精度的同时实现模型加速 在深度学习…

作者头像 李华