• 首页
  • AI产品
  • 解决方案
  • 帮助支持
  • 招商加盟
  • 关于我们
  • 联系我们
  • multilingual-e5-small + ONNX Runtime,使用 ONNX Runtime 的内置分词

    使用帮助 admin 发布时间:2026-03-15 浏览:122 次


    using System;

    using System.Collections.Generic;

    using System.IO;

    using System.Linq;

    using Microsoft.ML.OnnxRuntime;

    using Microsoft.ML.OnnxRuntime.Tensors;


    public class MultilingualE5Embedding : IDisposable

    {

        private readonly InferenceSession _session;

        private const int EmbeddingSize = 384;

        private const int MaxSeqLen = 128;


        // ======================

        // 删掉所有单例代码!!!

        // ======================


        public MultilingualE5Embedding()

        {

            string modelPath = Path.Combine(

                AppContext.BaseDirectory,

                "MLModels",

                "multilingual-e5-small",

                "model.onnx"

            );


            var options = new SessionOptions();

            options.AppendExecutionProvider_CPU(0);

            options.IntraOpNumThreads = 1;

            _session = new InferenceSession(modelPath, options);

        }


        public float[] Encode(string text)

        {

            if (string.IsNullOrWhiteSpace(text))

                return new float[EmbeddingSize];


            string input = $"query: {text.Trim()}";


            long[] inputIds;

            long[] attentionMask;

            long[] tokenTypeIds;

            EncodeInput(input, out inputIds, out attentionMask, out tokenTypeIds);


            var inputs = new List<NamedOnnxValue>

            {

                NamedOnnxValue.CreateFromTensor("input_ids", ToTensor(inputIds)),

                NamedOnnxValue.CreateFromTensor("attention_mask", ToTensor(attentionMask)),

                NamedOnnxValue.CreateFromTensor("token_type_ids", ToTensor(tokenTypeIds))

            };


            using var results = _session.Run(inputs);

            var lastHidden = results[0].AsTensor<float>();


            float[] embedding = new float[EmbeddingSize];

            for (int i = 0; i < EmbeddingSize; i++)

                embedding[i] = lastHidden[0, 0, i];


            return embedding;

        }


        private void EncodeInput(string text, out long[] inputIds, out long[] attentionMask, out long[] tokenTypeIds)

        {

            List<long> ids = new List<long> { 0 };


            foreach (char c in text)

                ids.Add(CharToId(c));


            ids.Add(2);


            while (ids.Count < MaxSeqLen)

                ids.Add(1);


            if (ids.Count > MaxSeqLen)

                ids = ids.Take(MaxSeqLen).ToList();


            inputIds = ids.ToArray();

            attentionMask = inputIds.Select(i => i != 1 ? 1L : 0L).ToArray();

            tokenTypeIds = new long[MaxSeqLen];

        }


        private long CharToId(char c)

        {

            if (c >= 32 && c <= 126) return c + 100;

            return 3;

        }


        private DenseTensor<long> ToTensor(long[] array)

        {

            return new DenseTensor<long>(array, new[] { 1, array.Length });

        }


        public void Dispose() => _session?.Dispose();

    }


    // 向量工具类

    public static class VectorHelper

    {

        public static byte[] Serialize(float[] vector)

        {

            byte[] bytes = new byte[vector.Length * 4];

            Buffer.BlockCopy(vector, 0, bytes, 0, bytes.Length);

            return bytes;

        }


        public static float[] Deserialize(byte[] bytes)

        {

            float[] vector = new float[bytes.Length / 4];

            Buffer.BlockCopy(bytes, 0, vector, 0, bytes.Length);

            return vector;

        }


        public static float CosineSimilarity(float[] a, float[] b)

        {

            if (a == null || b == null || a.Length != b.Length) return 0;

            float dot = 0, magA = 0, magB = 0;

            for (int i = 0; i < a.Length; i++)

            {

                dot += a[i] * b[i];

                magA += a[i] * a[i];

                magB += b[i] * b[i];

            }

            return dot / (float)Math.Sqrt(magA * magB);

        }

    }



    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    using Microsoft.ML.Tokenizers;

    using System.IO;

    using System;

    using System.Collections.Generic;


    namespace 智能客服.Services

    {

        public static class VectorHelper

        {

            // float[] → byte[] 存入数据库

            public static byte[] Serialize(float[] vector)

            {

                byte[] bytes = new byte[vector.Length * 4];

                Buffer.BlockCopy(vector, 0, bytes, 0, bytes.Length);

                return bytes;

            }


            // byte[] → float[] 从数据库读取

            public static float[] Deserialize(byte[] bytes)

            {

                float[] vector = new float[bytes.Length / 4];

                Buffer.BlockCopy(bytes, 0, vector, 0, bytes.Length);

                return vector;

            }


            // 余弦相似度

            public static float CosineSimilarity(float[] a, float[] b)

            {

                if (a == null || b == null || a.Length != b.Length) return 0;


                float dot = 0, magA = 0, magB = 0;

                for (int i = 0; i < a.Length; i++)

                {

                    dot += a[i] * b[i];

                    magA += a[i] * a[i];

                    magB += b[i] * b[i];

                }

                return dot / ((float)Math.Sqrt(magA) * (float)Math.Sqrt(magB));

            }

        }

    }



    使用示例:

    // 为问题生成向量(使用 "passage:" 前缀)

    using var embed = new MultilingualE5Embedding();

    float[] vec = embed.Encode(question); // 自动带 query: 前缀

    byte[] blob = VectorHelper.Serialize(vec);


    

    在线咨询

    点击这里给我发消息售前咨询专员

    点击这里给我发消息售后服务专员

    在线咨询

    免费通话

    24h咨询:19245332011


    如您有问题,可以咨询我们的24H咨询电话!

    免费通话

    微信扫一扫

    微信联系
    返回顶部