zerolog 包提供了一个快速简单的专用于 JSON 输出的日志记录器。
Zerolog 的 API 旨在提供出色的开发者体验和惊人的性能。其独特的链式 API 使 zerolog 能够通过避免分配和反射来编写 JSON(或 CBOR)日志事件。
Uber 的 zap 库首创了这种方法。Zerolog 在此基础上更进一步,提供了更简单易用的 API 和更好的性能。
为了保持代码库和 API 的简洁,zerolog 只专注于高效的结构化日志记录。通过提供的(但效率较低的)zerolog.ConsoleWriter
可以实现控制台上的美化日志输出。
了解谁在使用 zerolog并将你的公司/项目添加到列表中。
context.Context
集成net/http
集成go get -u github.com/rs/zerolog/log
对于简单的日志记录,导入全局日志记录包 github.com/rs/zerolog/log
package main import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { // UNIX 时间比大多数时间戳更快且更小 zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Print("hello world") } // 输出: {"time":1516134303,"level":"debug","message":"hello world"}
注意:默认情况下,日志写入
os.Stderr
注意:log.Print
的默认日志级别是 trace
zerolog 允许以键值对的形式向日志消息添加数据。添加到消息中的数据为日志事件提供了"上下文",这对调试以及众多其他用途至关重要。以下是一个示例:
package main import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Debug(). Str("Scale", "833 cents"). Float64("Interval", 833.09). Msg("Fibonacci is everywhere") log.Debug(). Str("Name", "Tom"). Send() } // 输出: {"level":"debug","Scale":"833 cents","Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere"} // 输出: {"level":"debug","Name":"Tom","time":1562212768}
你会注意到在上面的示例中,添加上下文字段时,字段是强类型的。你可以在这里找到支持的字段的完整列表
package main import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Info().Msg("hello world") } // 输出: {"time":1516134303,"level":"info","message":"hello world"}
非常重要的是要注意,当使用 zerolog 链式 API 时,如上所示(
log.Info().Msg("hello world")
),链必 须包含Msg
或Msgf
方法调用。如果你忘记添加这两个方法中的任何一个,日志将不会记录,并且没有编译时错误来提醒你这一点。
zerolog 允许在以下级别(从高到低)进行日志记录:
zerolog.PanicLevel
, 5)zerolog.FatalLevel
, 4)zerolog.ErrorLevel
, 3)zerolog.WarnLevel
, 2)zerolog.InfoLevel
, 1)zerolog.DebugLevel
, 0)zerolog.TraceLevel
, -1)你可以使用 zerolog 包中的 SetGlobalLevel
函数将全局日志级别设置为上述任何选项,传入给定的常量之一,例如 zerolog.InfoLevel
将是"info"级别。无论选择哪个级别,所有级别大于或等于该级别的日志都将被记录。要完全关闭日志记录,请传递 zerolog.Disabled
常量。
这个示例使用命令行标志来演示根据所选日志级别的不同输出。
package main import ( "flag" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix debug := flag.Bool("debug", false, "sets log level to debug") flag.Parse() // 本示例的默认级别为 info,除非存在 debug 标志 zerolog.SetGlobalLevel(zerolog.InfoLevel) if *debug { zerolog.SetGlobalLevel(zerolog.DebugLevel) } log.Debug().Msg("This message appears only when log level set to Debug") log.Info().Msg("This message appears when log level set to Debug or Info") if e := log.Debug(); e.Enabled() { // 仅在启用时计算日志输出。 value := "bar" e.Str("foo", value).Msg("some debug message") } }
Info 输出(无标志)
$ ./logLevelExample {"time":1516387492,"level":"info","message":"This message appears when log level set to Debug or Info"}
Debug 输出(设置 debug 标志)
$ ./logLevelExample -debug {"time":1516387573,"level":"debug","message":"This message appears only when log level set to Debug"} {"time":1516387573,"level":"info","message":"This message appears when log level set to Debug or Info"} {"time":1516387573,"level":"debug","foo":"bar","message":"some debug message"}
你可以选择使用Log
方法进行无特定级别的日志记录。你也可以通过在Msg
方法的msg string
参数中设置空字符串来不写入消息。以下示例演示了这两种方式。
package main import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Log(). Str("foo", "bar"). Msg("") } // 输出: {"time":1494567715,"foo":"bar"}
你可以使用Err
方法记录错误
package main import ( "errors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix err := errors.New("似乎这里有个错误") log.Error().Err(err).Msg("") } // 输出: {"level":"error","error":"似乎这里有个错误","time":1609085256}
错误的默认字段名是
error
,你可以通过设置zerolog.ErrorFieldName
来 满足你的需求。
使用github.com/pkg/errors
,你可以为错误添加格式化的堆栈跟踪。
package main import ( "github.com/pkg/errors" "github.com/rs/zerolog/pkgerrors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack err := outer() log.Error().Stack().Err(err).Msg("") } func inner() error { return errors.New("似乎这里有个错误") } func middle() error { err := inner() if err != nil { return err } return nil } func outer() error { err := middle() if err != nil { return err } return nil } // 输出: {"level":"error","stack":[{"func":"inner","line":"20","source":"errors.go"},{"func":"middle","line":"24","source":"errors.go"},{"func":"outer","line":"32","source":"errors.go"},{"func":"main","line":"15","source":"errors.go"},{"func":"main","line":"204","source":"proc.go"},{"func":"goexit","line":"1374","source":"asm_amd64.s"}],"error":"似乎这里有个错误","time":1609086683}
必须设置zerolog.ErrorStackMarshaler才能输出堆栈信息。
package main import ( "errors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) func main() { err := errors.New("收债人的一生都在应对紧张局势") service := "myservice" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Fatal(). Err(err). Str("service", service). Msgf("无法启动%s", service) } // 输出: {"time":1516133263,"level":"fatal","error":"收债人的一生都在应对紧张局势","service":"myservice","message":"无法启动myservice"} // exit status 1
注意:即使日志记录器被禁用,使用
Msgf
也会产生一次内存分配。
logger := zerolog.New(os.Stderr).With().Timestamp().Logger() logger.Info().Str("foo", "bar").Msg("你好,世界") // 输出: {"level":"info","time":1494567715,"message":"你好,世界","foo":"bar"}
sublogger := log.With(). Str("component", "foo"). Logger() sublogger.Info().Msg("你好,世界") // 输出: {"level":"info","time":1494567715,"message":"你好,世界","component":"foo"}
要输出人类友好的、带颜色的日志,使用zerolog.ConsoleWriter
:
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) log.Info().Str("foo", "bar").Msg("你好,世界") // 输出: 3:04PM INF 你好,世界 foo=bar
自定义配置和格式化:
output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339} output.FormatLevel = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("| %-6s|", i)) } output.FormatMessage = func(i interface{}) string { return fmt.Sprintf("***%s****", i) } output.FormatFieldName = func(i interface{}) string { return fmt.Sprintf("%s:", i) } output.FormatFieldValue = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%s", i)) } log := zerolog.New(output).With().Timestamp().Logger() log.Info().Str("foo", "bar").Msg("你好,世界") // 输出: 2006-01-02T15:04:05Z07:00 | INFO | ***你好,世界**** foo:BAR
log.Info(). Str("foo", "bar"). Dict("dict", zerolog.Dict(). Str("bar", "baz"). Int("n", 1), ).Msg("你好,世界") // 输出: {"level":"info","time":1494567715,"foo":"bar","dict":{"bar":"baz","n":1},"message":"你好,世界"}
zerolog.TimestampFieldName = "t" zerolog.LevelFieldName = "l" zerolog.MessageFieldName = "m" log.Info().Msg("你好,世界") // 输出: {"l":"info","t":1494567715,"m":"你好,世界"}
log.Logger = log.With().Str("foo", "bar").Logger()
等同于Llongfile
:
log.Logger = log.With().Caller().Logger() log.Info().Msg("你好,世界") // 输出: {"level": "info", "message": "你好 ,世界", "caller": "/go/src/your_project/some_file:21"}
等同于Lshortfile
:
zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { return filepath.Base(file) + ":" + strconv.Itoa(line) } log.Logger = log.With().Caller().Logger() log.Info().Msg("你好,世界") // 输出: {"level": "info", "message": "你好,世界", "caller": "some_file:21"}
如果你的写入器可能很慢或不是线程安全的,而你需要确保日志生产者永远不会被慢速写入器拖慢,你可以使用diode.Writer
,如下所示:
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) { fmt.Printf("日志记录器丢弃了 %d 条消息", missed) }) log := zerolog.New(wr) log.Print("测试")
要使用此功能,你需要安装code.cloudfoundry.org/go-diodes
。
sampled := log.Sample(&zerolog.BasicSampler{N: 10}) sampled.Info().Msg("每10条消息记录一次") // 输出: {"time":1494567715,"level":"info","message":"每10条消息记录一次"}
更高级的采样:
// 每1秒期间允许5条debug消息。 // 超过5条debug消息后,每100条debug消息记录1条。 // 其他级别不进行采样。 sampled := log.Sample(zerolog.LevelSampler{ DebugSampler: &zerolog.BurstSampler{ Burst: 5, Period: 1*time.Second, NextSampler: &zerolog.BasicSampler{N: 100}, }, }) sampled.Debug().Msg("你好,世界")
// 输出: {"time":1494567715,"level":"debug","message":"hello world"}
### 钩子
```go
type SeverityHook struct{}
func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
if level != zerolog.NoLevel {
e.Str("severity", level.String())
}
}
hooked := log.Hook(SeverityHook{})
hooked.Warn().Msg("")
// 输出: {"level":"warn","severity":"warn"}
ctx := log.With().Str("component", "module").Logger().WithContext(ctx) log.Ctx(ctx).Info().Msg("hello world") // 输出: {"component":"module","level":"info","message":"hello world"}
log := zerolog.New(os.Stdout).With(). Str("foo", "bar"). Logger() stdlog.SetFlags(0) stdlog.SetOutput(log) stdlog.Print("hello world") // 输出: {"foo":"bar","message":"hello world"}
Go 上下文通常在整个 Go 代码中传递,这可以帮助你将 Logger 传递到可能难以注入的地方。可以使用 Logger.WithContext(ctx)
将 Logger
实例附加到 Go 上下文(context.Context
)中,并使用 zerolog.Ctx(ctx)
从中提取。例如:
func f() { logger := zerolog.New(os.Stdout) ctx := context.Background() // 将 Logger 附加到 context.Context ctx = logger.WithContext(ctx) someFunc(ctx) } func someFunc(ctx context.Context) { // 从 Go Context 获取 Logger。如果为 nil,则返回 // `zerolog.DefaultContextLogger`,如果 // `DefaultContextLogger` 为 nil,则返回一个禁用的日志记录器。 logger := zerolog.Ctx(ctx) logger.Info().Msg("Hello") }
第二种形式的 context.Context
集成允许你将当前的 context.Context 传递到记录的事件中,并从钩子中检索它。这对于记录存储在 Go 上下文中的跟踪和跨度 ID 或其他信息非常有用,并有助于在某些系统中统一日志记录和跟踪:
type TracingHook struct{} func (h TracingHook) Run(e *zerolog.Event, level zerolog.Level, msg string) { ctx := e.GetCtx() spanId := getSpanIdFromContext(ctx) // 根据你的跟踪框架 e.Str("span-id", spanId) } func f() { // 设置日志记录器 logger := zerolog.New(os.Stdout) logger = logger.Hook(TracingHook{}) ctx := context.Background() // 使用 Ctx 函数使上下文对钩子可用 logger.Info().Ctx(ctx).Msg("Hello") }
net/http
集成github.com/rs/zerolog/hlog
包提供了一些辅助函数,用于将 zerolog 与 http.Handler
集成。
在这个例子中,我们使用 alice 来安装日志记录器,以提高可读性。
log := zerolog.New(os.Stdout).With(). Timestamp(). Str("role", "my-service"). Str("host", host). Logger() c := alice.New() // 安装日志处理器,默认输出到控制台 c = c.Append(hlog.NewHandler(log)) // 安装一些提供的额外处理器来设置请求的上下文字段。 // 通过这个处理器,我们所有的日志都会带有一些预填充的字段。 c = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) { hlog.FromRequest(r).Info(). Str("method", r.Method). Stringer("url", r.URL). Int("status", status). Int("size", size). Dur("duration", duration). Msg("") })) c = c.Append(hlog.RemoteAddrHandler("ip")) c = c.Append(hlog.UserAgentHandler("user_agent")) c = c.Append(hlog.RefererHandler("referer")) c = c.Append(hlog.RequestIDHandler("req_id", "Request-Id")) // 这是你最终的处理器 h := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 从请求的上下文中获取日志记录器。你可以安全地假设它 // 总是存在的:如果处理器被移除,hlog.FromRequest // 将返回一个无操作的日志记录器。 hlog.FromRequest(r).Info(). Str("user", "current user"). Str("status", "ok"). Msg("Something happened") // 输出: {"level":"info","time":"2001-02-03T04:05:06Z","role":"my-service","host":"local-hostname","req_id":"b4g0l5t6tfid6dtrapu0","user":"current user","status":"ok","message":"Something happened"} })) http.Handle("/", h) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal().Err(err).Msg("Startup failed") }
可以使用 zerolog.MultiLevelWriter
将日志消息发送到多个输出。
在这个例子中,我们将日志消息同时发送到 os.Stdout
和内置的 ConsoleWriter。
func main() { consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout} multi := zerolog.MultiLevelWriter(consoleWriter, os.Stdout) logger := zerolog.New(multi).With().Timestamp().Logger() logger.Info().Msg("Hello World!") } // 输出 (第1行: 控制台; 第2行: Stdout) // 12:36PM INF Hello World! // {"level":"info","time":"2019-11-07T12:36:38+03:00","message":"Hello World!"}
可以更改一些设置,这些设置将应用于所有日志记录器:
log.Logger
:你可以设置这个值来自定义全局日志记录器(用于包级别方法的日志记录器)。zerolog.SetGlobalLevel
:可以提高所有日志记录器的最低级别。使用 zerolog.Disabled
调用此函数可以完全禁用日志记录(静默模式)。zerolog.DisableSampling
:如果参数为 true
,所有采样日志记录器将停止采样并发出 100% 的日志事件。zerolog.TimestampFieldName
:可以设置为自定义 Timestamp
字段名。zerolog.LevelFieldName
:可以设置为自定义级别字段名。zerolog.MessageFieldName
:可以设置为自定义消息字段名。zerolog.ErrorFieldName
:可以设置为自定义 Err
字段名。zerolog.TimeFieldFormat
:可以设置为自定义 Time
字段值的格式。如果设置为 zerolog.TimeFormatUnix
、zerolog.TimeFormatUnixMs
或 zerolog.TimeFormatUnixMicro
,时间将格 式化为 UNIX 时间戳。zerolog.DurationFieldUnit
:可以设置为自定义由 Dur
添加的 time.Duration 类型字段的单位(默认:time.Millisecond
)。zerolog.DurationFieldInteger
:如果设置为 true
,Dur
字段将格式化为整数而不是浮点数(默认:false
)。zerolog.ErrorHandler
:当 zerolog 无法在其输出上写入事件时调用。如果未设置,错误将打印到标准错误输出。此处理程序必须是线程安全的且非阻塞的。zerolog.FloatingPointPrecision
:如果设置为非 -1 的值,控制在 JSON 中格式化浮点数时的位数。有关更多详细信息,请参见 strconv.FormatFloat。Str
Bool
Int
、Int8
、Int16
、Int32
、Int64
Uint
、Uint8
、Uint16
、Uint32
、Uint64
Float32
、Float64
Err
:接受一个error
并使用zerolog.ErrorFieldName
字段名将其渲染为字符串。Func
:仅在启用该级别时运行func
。Timestamp
:插入一个使用zerolog.TimestampFieldName
字段名的时间戳字段,格式化使用zerolog.TimeFieldFormat
。Time
:添加一个使用zerolog.TimeFieldFormat
格式化的时间字段。Dur
:添加一个time.Duration
字段。Dict
:作为事件的字段添加一个子键/值。RawJSON
:添加一个已编码JSON([]byte
)的字段。Hex
:添加一个格式化为十六进制字符串的值字段([]byte
)。Interface
:使用反射来序列化类型。大多数字段也以切片格式提供(Strs
用于[]string
,Errs
用于[]error
等)。
除了默认的JSON编码外,zerolog
还可以使用CBOR编码生成二进制日志。编码选择可以在编译时使用构建标签binary_log
来决定,如下所示:
go build -tags binary_log .
要解码二进制编码的日志文件,可以使用任何CBOR解码器。经测试可与zerolog库一起使用的解码器是CSD。
zerolog
实现的grpclog.LoggerV2
接口zerolog
实现的Mapped Diagnostic Context
接口zerolog
实现的logr.LogSink
接口更全面和最新的基准测试请参见logbench。
所有操作都是无分配的(这些数字包括JSON编码):
BenchmarkLogEmpty-8 100000000 19.1 ns/op 0 B/op 0 allocs/op BenchmarkDisabled-8 500000000 4.07 ns/op 0 B/op 0 allocs/op BenchmarkInfo-8 30000000 42.5 ns/op 0 B/op 0 allocs/op BenchmarkContextFields-8 30000000 44.9 ns/op 0 B/op 0 allocs/op BenchmarkLogFields-8 10000000 184 ns/op 0 B/op 0 allocs/op
有几个包含zerolog的Go日志基准测试和比较。
使用Uber的zap比较基准:
记录一条消息和10个字段:
库 | 时间 | 分配字节数 | 分配对象数 |
---|---|---|---|
zerolog | 767 ns/op | 552 B/op | 6 allocs/op |
:zap: zap | 848 ns/op | 704 B/op | 2 allocs/op |
:zap: zap (sugared) | 1363 ns/op | 1610 B/op | 20 allocs/op |
go-kit | 3614 ns/op | 2895 B/op | 66 allocs/op |
lion | 5392 ns/op | 5807 B/op | 63 allocs/op |
logrus | 5661 ns/op | 6092 B/op | 78 allocs/op |
apex/log | 15332 ns/op | 3832 B/op | 65 allocs/op |
log15 | 20657 ns/op | 5632 B/op | 93 allocs/op |
使用已有10个上下文字段的logger记录一条消息:
库 | 时间 | 分配字节数 | 分配对象数 |
---|---|---|---|
zerolog | 52 ns/op | 0 B/op | 0 allocs/op |
:zap: zap | 283 ns/op | 0 B/op | 0 allocs/op |
:zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |
lion | 2702 ns/op | 4074 B/op | 38 allocs/op |
go-kit | 3378 ns/op | 3046 B/op | 52 allocs/op |
logrus | 4309 ns/op | 4564 B/op | 63 allocs/op |
apex/log | 13456 ns/op | 2898 B/op | 51 allocs/op |
log15 | 14179 ns/op | 2642 B/op | 44 allocs/op |
记录一个静态字符串,不带任何上下文或printf
风格的模板:
库 | 时间 | 分配字节数 | 分配对象数 |
---|---|---|---|
zerolog | 50 ns/op | 0 B/op | 0 allocs/op |
:zap: zap | 236 ns/op | 0 B/op | 0 allocs/op |
标准库 | 453 ns/op | 80 B/op | 2 allocs/op |
:zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |
go-kit | 508 ns/op | 656 B/op | 13 allocs/op |
lion | 771 ns/op | 1224 B/op | 10 allocs/op |
logrus | 1244 ns/op | 1505 B/op | 27 allocs/op |
apex/log | 2751 ns/op | 584 B/op | 11 allocs/op |
log15 | 5181 ns/op | 1592 B/op | 26 allocs/op |
请注意,zerolog不会对字段进行去重。多次使用相同的键会在最终的JSON中创建多个键:
logger := zerolog.New(os.Stderr).With().Timestamp().Logger() logger.Info(). Timestamp(). Msg("dup") // 输出: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"}
在这种情况下,许多消费者会取最后一个值,但这并不能保证;如有疑问,请检查您的消费者。
使用UpdateContext时要小心。它不是并发安全的。使用With方法创建一个子logger:
func handler(w http.ResponseWriter, r *http.Request) { // 创建一个子logger以确保并发安全 logger := log.Logger.With().Logger() // 添加上下文字段,例如来自HTTP头的User-Agent logger.UpdateContext(func(c zerolog.Context) zerolog.Context { ... }) }
AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号