fastText是facebook开源的一个词向量与文本分类工具 https://github.com/facebookresearch/fastText
提供了python和c的接口。 通过Java使用fastText,搜到了这个项目 https://github.com/vinhkhuc/JFastText ,使用起来很方便,性能也不错;但是有一个问题,就是如果模型多次更新,就会产生僵尸进程导致程序挂掉,并引起机器的负载升高。
所以决定使用JNI的方式调用fastText
步骤: 1、编写Java程序
public class FastTextJNI {
public static FastTextJNI ftJNI;
private static String LIB_PATH = ConstantsConfig.CONFIG_BASE_PATH + "libfasttext.so";
public native long FastTextJNILoadModel(String fileName);
public native float[] FastTextSentenceVector(long modelHandle, String words);
public native void FastTextJNIReleaseModel(long modelHandle);
public static void init(){
System.load(LIB_PATH);
ftJNI = new FastTextJNI();
}
public FastTextJNI(){
}
public FastTextJNI(String fileName){
FastTextJNILoadModel(fileName);
}
public float[] getSentenceVector(long modelHandle, String words){
return FastTextSentenceVector(modelHandle, words);
}
public void finalize(Long modelHandle){
FastTextJNIReleaseModel(modelHandle);
modelHandle = (long) 0;
}
}
<!--more--> 2、编译Java程序 javac FastTextJNI.java
3、继续编译生成c的头文件(给c/c++程序用) javah -jni -classpath . FastTextJNI,生成了头文件FastTextJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class FastTextJNI */
#ifndef FastTextJNI
#define FastTextJNI
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong JNICALL Java_FastTextJNI_FastTextJNILoadModel
(JNIEnv *, jobject, jstring);
JNIEXPORT jfloatArray JNICALL Java_FastTextJNI_FastTextSentenceVector
(JNIEnv *, jobject, jlong, jstring);
JNIEXPORT void JNICALL Java_FastTextJNI_FastTextJNIReleaseModel
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}
#endif
#endif
4、新建cpp文件,实现jni编译生成的头文件中的函数
#include <iostream>
#include <sstream>
#include "FastTextJNI.h"
#include "fastText/src/fasttext.h"
using namespace fasttext;
JNIEXPORT jlong JNICALL Java_FastTextJNI_FastTextJNILoadModel
(JNIEnv *jenv, jobject jobj, jstring jmodelName)
{
const char* modelName = jenv->GetStringUTFChars(jmodelName, 0);
FastText *fastText = new FastText();
fastText->loadModel(modelName);
if(modelName)
{
jenv->ReleaseStringUTFChars(jmodelName, modelName);
}
return (jlong)fastText;
}
JNIEXPORT jfloatArray JNICALL Java_FastTextJNI_FastTextSentenceVector
(JNIEnv *jenv, jobject jobj, jlong jmodelHandle, jstring jwords)
{
FastText* fastText = (FastText*)(jmodelHandle);
const char* words = jenv->GetStringUTFChars(jwords, 0);
char* wordschar = const_cast<char*>(words);
std::istringstream in(wordschar);
fasttext::Vector vec(20);
try{
fastText->getSentenceVector(in, vec);
} catch(std::exception& e) {
std::cout << e.what() << std::endl;
}
float* data = vec.data_;
jfloatArray result;
int len = 20;
result = jenv->NewFloatArray(len);
jenv->SetFloatArrayRegion(result, 0, len, data);
return result;
}
JNIEXPORT void JNICALL Java_FastTextJNI_FastTextJNIReleaseModel
(JNIEnv *jenv, jobject jobj, jlong jmodelHandle)
{
if(jmodelHandle)
{
delete (FastText*)(jmodelHandle);
}
}
5、最后编译so库,生成 libfasttext.so 文件使用
g++ -fpic -shared a.cpp -o libfasttext.so -I./ -I/opt/soft/jdk/jdk1.6.0_45/include -I/opt/soft/jdk/jdk1.6.0_45/include/linux
生成so库之后,执行ldd libfasttext.so,如果有关联其他库说明生成库没有问题
留言