• C#使用iKvm黑科技无缝接入JVM生态
  • 发布于 2个月前
  • 198 热度
    0 评论
一.前言
最近在开发AIHub的时候想找个C#能用的命名实体识别库,但一直没找到,AI生态方面C#确实不太丰富,这块还是得Python,但我又不想跟LLM一样用gRPC的方式来调用,感觉有点麻烦。这时候发现好像JVM生态有不少这类NLP工具,比如 Standford NLP 、HanLP这类。所以就想到之前在网上看到的iKvm,我直接把JVM生态白嫖来使用😃

二.关于iKvm
看官方的介绍:
IKVM is an implementation of Java for the Microsoft .NET platform. It can be used to quickly and easily:

Execute compiled Java code (bytecode) on .NET Framework or .NET Core
Convert bytecode to a .NET assembly to directly access its API in a .NET project
These tasks can be done without porting source code to .NET.

有两种工作方式:
1.直接在C#里调用 jar 包执行

2.将 jar 包转译为 .Net 平台的 dll ,然后引用执行


一般选第二种就行,第一种就是动态调用,根本没代码提示,不想考虑这种方式。

iKvm 其实是一套体系来的,里面包含了完整的 JDK 标准库和运行时啥的,我粗略看了下,什么 swing、xml、media啥的一应俱全,还能支持 jdk 的反射。
并且还附带有现代的构建工具 maven!

PS: gradle 不知道有没有,我还没试过。

三.关于依赖处理
虽说 iKvm 支持 maven 非常的方便,但是它并不能处理一个包中的依赖关系!例如引用了 StarAI 这个包,它又依赖于 Transformer 这个库,在maven中会自动下载所有依赖进行 build。但是 iKvm 的 maven 没办法自动处理依赖,所以只能手动把 StarAI 和 transformer 这俩库都添加到配置里。

四.开始使用
本文以 HanLP 为例。
依赖准备
首先添加俩 nuget 依赖
dotnet add package IKVM
dotnet add package IKVM.Maven.Sdk
或者直接编辑项目文件
<ItemGroup>
    <PackageReference Include="IKVM" Version="8.6.4" />
    <PackageReference Include="IKVM.Maven.Sdk" Version="1.5.5" />
</ItemGroup>
然后再项目文件里面添加 maven 依赖,直接从 mvn repository 上复制下来就完事了,非常的方便!给不熟悉 Java 的同学指个路: https://mvnrepository.com/
<ItemGroup>
    <MavenReference Include="hanlp">
        <groupId>com.hankcs</groupId>
        <artifactId>hanlp</artifactId>
        <version>portable-1.8.4</version>
    </MavenReference>
</ItemGroup>
保存,之后IDE会自动执行操作,会自动下载 iKvm 需要的依赖,各平台的 JDK 和 runtime 之类的,并且会自动从 maven 上把 jar 包下载下来并转译成 .Net 平台的 dll。这个过程需要一段时间,请耐心等待。

如果没有自动执行请手动运行
dotnet restore
dotnet build

开始编码
这里以 HanLP 的句子成分分析功能为例
using com.hankcs.hanlp.model.crf;
using com.hankcs.hanlp.model.perceptron;
using com.hankcs.hanlp.seg;
using com.hankcs.hanlp.seg.common;
namespace AIHub.Algo.HanLP;

public class NER {
    private readonly string _modelPath;
    // 堆代码 duidaima.com
    public NER(string modelPath) {
        _modelPath = modelPath;
    }

    public void Recognize(string input) {
        PerceptronLexicalAnalyzer analyzer = new PerceptronLexicalAnalyzer(
            Path.Combine(_modelPath, "cws.bin"),
            Path.Combine(_modelPath, "pos.bin"),
            Path.Combine(_modelPath, "ner.bin")
        );

        var result = analyzer.analyze(input);
        Console.WriteLine(result);
    }
}
测试时直接调用 Recognize 方法即可。
用户评论