命令行中执行 ollama pull bge-large,或者 ollama pull chroma/all-minilm-l6-v2-f32,这两个模型都可以用来计算向量,拉取好后调用Ollama的API,不能直接运行模型,ollama run bge-large,会报错Error: "bge-large" does not support generate。
static List Calculate(string text, string model = "bge-large")
{
string response = GenerateEmbedding(model, text);
JavaScriptSerializer serializer = new JavaScriptSerializer();
EmbeddingResponse result = serializer.Deserialize(response);
return result.embedding;
}
static string GenerateEmbedding(string model, string text)
{
// 构建请求 JSON
string requestJson = new JavaScriptSerializer().Serialize(new
{
model = model,
prompt = text
});
// 创建 HTTP 请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:11434/api/embeddings");
request.Method = "POST";
request.ContentType = "application/json";
request.Timeout = 30000; // 30秒超时
// 设置请求体
byte[] requestBytes = Encoding.UTF8.GetBytes(requestJson);
request.ContentLength = requestBytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestBytes, 0, requestBytes.Length);
}
// 获取响应
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
///
/// 计算两个向量的余弦相似度
///
/// 向量A
/// 向量B
/// 相似度(范围:-1 到 1)
static double CalculateCosineSimilarity(List vectorA, List vectorB)
{
// 检查向量维度是否一致
if (vectorA.Count != vectorB.Count)
{
throw new ArgumentException("两个向量的维度必须相同");
}
// 检查向量是否为空
if (vectorA.Count == 0)
{
throw new ArgumentException("向量不能为空");
}
double dotProduct = 0; // 点积
double normA = 0; // 向量A的模长
double normB = 0; // 向量B的模长
// 遍历计算点积和模长
for (int i = 0; i < vectorA.Count; i++)
{
dotProduct += vectorA[i] * vectorB[i]; // 累加点积
normA += vectorA[i] * vectorA[i]; // 累加A的平方和
normB += vectorB[i] * vectorB[i]; // 累加B的平方和
}
// 计算模长(开平方)
normA = Math.Sqrt(normA);
normB = Math.Sqrt(normB);
// 避免除以零(模长为0的向量无意义)
if (normA == 0 || normB == 0)
{
return 0;
}
// 计算余弦相似度
return dotProduct / (normA * normB);
}
private void btnCosine_Click(object sender, EventArgs e)
{
try
{
string text1 = "我爱自然语言处理";
string text2 = "我爱处理";
List vectorA = Calculate(text1);
List vectorB = Calculate(text2);
double similarity = CalculateCosineSimilarity(vectorA, vectorB);
MessageBox.Show($"余弦相似度:{similarity:F6}");
}
catch (Exception ex)
{
Console.WriteLine($"错误: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($" 内部错误: {ex.InnerException.Message}");
}
}
}