你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 aspnetcore 原生的 MSDI 中,如何实现呢?本文将介绍如何通过自定义工厂来实现。
我们现在恰好有基于 Json 和 MessagePack 的两种序列化器
有一个接口是这样的
publicinterfaceISerializer{byte[] Serialize<T>(T obj);T Deserialize<T>(ReadOnlySpan<byte> data);}
并且由两个不同的实现
// JsonpublicclassMyJsonSerializer : ISerializer{publicbyte[] Serialize<T>(T obj) {thrownew NotImplementedException(); }public T Deserialize<T>(ReadOnlySpan<byte> data) {thrownew NotImplementedException(); }}// MessagePackpublicclassMyMessagePackSerializer : ISerializer{publicbyte[] Serialize<T>(T obj) {thrownew NotImplementedException(); }public T Deserialize<T>(ReadOnlySpan<byte> data) {thrownew NotImplementedException(); }}
我有一个服务,需要使用这两种序列化器中的一种。
publicclassMyService{publicobjectDoSomething(string dataType, ReadOnlySpan<byte> data) {// 根据 dataType 来决定使用哪种序列化器 }}
使用委托来定义获取服务的方法
我们可以通过委托来定义获取服务的方法,如下
publicdelegate ISerializer SerializerFactory(string dataType);
然后在 ConfigureServices 方法中注册
services.AddSingleton<MyJsonSerializer>();services.AddSingleton<MyMessagePackSerializer>();services.AddSingleton<SerializerFactory>(sp =>{return dataType => {switch (dataType) {case"json":return sp.GetRequiredService<MyJsonSerializer>();case"msgpack":return sp.GetRequiredService<MyMessagePackSerializer>();default:thrownew NotSupportedException(); } };});
这样我们就可以在 MyService 中通过委托来获取服务了
publicclassMyService{privatereadonly SerializerFactory _serializerFactory;publicMyService(SerializerFactory serializerFactory) { _serializerFactory = serializerFactory; }publicobjectDoSomething(string dataType, ReadOnlySpan<byte> data) {var serializer = _serializerFactory(dataType);return serializer.Deserialize<object>(data); }}
基于配置来改变工厂
因为本质是通过委托来获取服务,所以我们可以通过配置来改变委托的行为,如下
publicstaticclassSerializerFactoryExtensions{publicstatic SerializerFactory CreateSerializerFactory(this IServiceProvider sp) {// get mapping from configurationvar mapping = sp.GetRequiredService<IConfiguration>() .GetSection("SerializerMapping") .Get<Dictionary<string, string>>();return dataType => {var serializerType = mapping[dataType];return (ISerializer)sp.GetRequiredService(Type.GetType(serializerType)); }; }}
然后在 appsettings.json 中配置
{"SerializerMapping":{"json":"WebApplication1.MyJsonSerializer","msgpack":"WebApplication1.MyMessagePackSerializer"}}
然后在 ConfigureServices 方法中注册
services.AddSingleton<MyJsonSerializer>();services.AddSingleton<MyMessagePackSerializer>();services.AddSingleton(SerializerFactoryExtensions.CreateSerializerFactory);
总结
本篇文章介绍了如何通过自定义工厂来实现基于 key 的服务获取,这种方式在 aspnetcore 原生的 DI 中是原生支持的。
学术界的 SOTA 模型在落地部署到工业界应用到过程中,通常是要面临着低延迟(Latency)、高吞吐(Throughpout)、高效率(Efficiency)挑战的。而模型压缩算法可以将一个庞大而复杂的预训练模型转化为一个精简的小模型,从而减少对硬件的存储、带宽和计算需求,以达到加速模型推理和落地的目的。
近年来主流的模型压缩方法包括:数值量化(Data Quantization,也叫模型量化),模型稀疏化(Model sparsification,也叫模型剪枝 Model Pruning),知识蒸馏(Knowledge Distillation), 轻量化网络设计(Lightweight Network Design)和 张量分解(Tensor Decomposition)。
其中模型剪枝是一种应用非常广的模型压缩方法,其可以直接减少模型中的参数量。本文会对模型剪枝的定义、发展历程、分类以及算法原理进行详细的介绍。
模型剪枝(Pruning)也叫模型稀疏化,不同于模型量化对每一个权重参数进行压缩,稀疏化方法是尝试直接“删除”部分权重参数。模型剪枝的原理是通过剔除模型中 “不重要” 的权重,使得模型减少参数量和计算量,同时尽量保证模型的精度不受影响。