Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants