Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

关于hanlp.properties中定义的data路径问题 #380

Closed
fangyuan930917 opened this issue Jan 9, 2017 · 13 comments
Closed

关于hanlp.properties中定义的data路径问题 #380

fangyuan930917 opened this issue Jan 9, 2017 · 13 comments
Labels

Comments

@fangyuan930917
Copy link

最近一直在使用hanlp分词工具,发现hanlp.properties在data/dictionary路径的定义上并不灵活,root只能定死绝对路径。在将程序打包放到spark集群上运行,不可行。尝试改IOUtils的
public static InputStream newInputStream(String path) throws IOException
{
if (IOAdapter == null) return new FileInputStream(path);
return IOAdapter.open(path);
}
通过classloader的getresourceasStream方式读取,发现之后能实现将data放入到classpath下通过相对路径读取,但是牵一发动全身,很多地方都有异常,希望hancks大神有时间能解决下hanlp.properties只能通过绝对路径读入data的问题

@hankcs
Copy link
Owner

hankcs commented Jan 9, 2017

感谢建议

  1. root并没有限定非要用绝对路径,你可以用root=../之类的相对路径。但开发环境和生产环境中的“当前目录”几乎完全不一样,所以需要自行处理。在默认情况下,IOAdapter=com.hankcs.hanlp.corpus.io.FileIOAdapter,一定是基于普通文件系统的。
  2. 集群上其实更简单,可以来个root=hdfs://localhost:9000/hanlpdata/之类。然后写个HDFSIOAdapter,最后修改配置文件IOAdapter=com.xxx.HDFSIOAdapter即可
  3. 把data替换到jar包不是推荐方案,破坏了库的原本设计,任何修改库的方案都不推荐
  4. 你遇到的麻烦是因为你遇到问题先选择修改库,而不是利用库的现成接口。

@hankcs hankcs added the question label Jan 9, 2017
@hankcs
Copy link
Owner

hankcs commented Jan 9, 2017

另外,如果在集群的每个node下的classpath都放一份data,这会造成浪费和版本紊乱,也是不推荐的。

@cicido
Copy link

cicido commented Feb 5, 2017

考虑把词典文件放在hdfs是个不错的选择

@zzzhy
Copy link

zzzhy commented May 18, 2017

@hankcs 你说的接口可实现hdfs访问,我试了停用词hdfs存储,发现每次传过来的停用词path都不是hdfs的path,如果有时间我写个pr

@hankcs
Copy link
Owner

hankcs commented May 18, 2017

@zzzhy 应该与这个issue重复了:#530 欢迎测试

@zzzhy
Copy link

zzzhy commented May 18, 2017

@hankcs 我下载的1.3.3还没修复?

@zzzhy
Copy link

zzzhy commented May 18, 2017

@hankcs 何时更新下maven portable

@hankcs
Copy link
Owner

hankcs commented May 18, 2017

请测试无误后通知我,大概周末吧

@fishermanff
Copy link

@hankcs 您好,按照您说的方法,修改配置
root=hdfs://localhost:9000/hanlpdata/
IOAdapter=com.xxx.HDFSIOAdapter
而且在scala重写了接口:
class HadoopFileIoAdapter extends IIOAdapter {
@OverRide
def open(path: String): java.io.InputStream = {
val conf: Configuration = new Configuration();
val fs: FileSystem = FileSystem.get(URI.create(path), conf);
fs.open(new Path(path));
}

@Override
def create(path: String): java.io.OutputStream = {
    val conf: Configuration = new Configuration();
    val fs: FileSystem = FileSystem.get(URI.create(path), conf);
    fs.create(new Path(path));
}

}
HanLP.Config.IOAdapter = new HadoopFileIoAdapter();

也只能在单机spark下运行分词
scala> System.out.println(HanLP.segment("你好,欢迎使用HanLP汉语处理包!"));
[你好/vl, ,/w, 欢迎/v, 使用/v, HanLP/nx, 汉语/gi, 处理/vn, 包/v, !/w]

分发到节点的时候就出错了,请问你们在集群上使用的时候是否遇到过这种问题?需要注意哪些坑呢?
val a = sc.parallelize(Seq("中国的神威太湖之光计算机被用于天气预报","制药研究和工业设计等领域。"))
val res = a.map(e=>{
HanLP.segment(e).toString
})
res take 2 foreach println

Exit code: 255
Stack trace: ExitCodeException exitCode=255:
at org.apache.hadoop.util.Shell.runCommand(Shell.java:578)
at org.apache.hadoop.util.Shell.run(Shell.java:489)
at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:755)
at org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor.launchContainer(LinuxContainerExecutor.java:297)
at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:302)
at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:82)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

@cicido
Copy link

cicido commented Mar 28, 2018

一年之后继续做NLP了。重新看了下当时的问题。当时我在用spark分布式处理时,如果不把数据做成jar包分发的话,会出现另一个问题,HanLP那个类是不可序列化的,导致这个对象不能广播到其他节点上去,也就是不能进行分词。因而最终的方案是在每个分布式节点生成一个HanLP对象,并相应的加载词典。

@tanganyao
Copy link

@fishermanff 您后来分发到节点的问题解决了吗?我也遇到类似的问题了,可以分享下的解决方案吗

@Doobetter
Copy link

可以做一个分词服务,每次去调用接口

@hankcs
Copy link
Owner

hankcs commented Jan 1, 2020

感谢您对HanLP1.x的支持,我一直为没有时间回复所有issue感到抱歉,希望您提的问题已经解决。或者,您可以从《自然语言处理入门》中找到答案。

时光飞逝,HanLP1.x感谢您的一路相伴。我于东部标准时间2019年12月31日发布了HanLP1.x在上一个十年最后一个版本,代号为最后的武士。此后1.x分支将提供稳定性维护,但不是未来开发的焦点。

值此2020新年之际,我很高兴地宣布,HanLP2.0发布了。HanLP2.0的愿景是下一个十年的前沿NLP技术。为此,HanLP2.0采用TensorFlow2.0实现了最前沿的深度学习模型,通过精心设计的框架支撑下游NLP任务,在海量语料库上取得了最前沿的准确率。作为第一个alpha版本,HanLP 2.0.0a0支持分词、词性标注、命名实体识别、依存句法分析、语义依存分析以及文本分类。而且,这些功能并不仅限中文,而是面向全人类语种设计。HanLP2.0提供许多预训练模型,而终端用户仅需两行代码即可部署,深度学习落地不再困难。更多详情,欢迎观看HanLP2.0的介绍视频,或参与论坛讨论

展望未来,HanLP2.0将集成1.x时代继承下来的高效率务实风范,同时冲刺前沿研究,做工业界和学术界的两栖战舰,请诸君继续多多指教,谢谢。

@hankcs hankcs closed this as completed Jan 1, 2020
@hankcs hankcs added ignored and removed question labels Jan 1, 2020
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants