如何编写一个PaddleHub Module

    本示例代码可以参考senta_module_sample

    Module存在一个接口sentiment_classify,用于接收传入文本,并给出文本的情感倾向(正面/负面),支持python接口调用和命令行调用。

    1. senta_test = hub.Module(name="senta_test")
    2. senta_test.sentiment_classify(texts=["这部电影太差劲了"])
    1. hub run senta_test --input_text 这部电影太差劲了

    为了示例代码简单起见,我们使用一个非常简单的情感判断策略,当输入文本中带有词表中指定单词时,则判断文本倾向为负向,否则为正向

    创建一个senta_test的目录,并在senta_test目录下分别创建__init__.py、module.py、processor.py、vocab.list,其中

    1. tree senta_test
    2. senta_test/
    3. ├── vocab.list
    4. ├── __init__.py
    5. └── processor.py

    step 2. 实现辅助模块processor

    在processor.py中实现一个load_vocab接口用于读取词表

    1. def load_vocab(vocab_path):
    2. with open(vocab_path) as file:
    3. return file.read().split()

    module.py文件为Module的入口代码所在,我们需要在其中实现预测逻辑。

    step 3_1. 引入必要的头文件

    step 3_2. 定义SentaTest类

    module.py中需要有一个继承了hub.Module的类存在,该类负责实现预测逻辑,并使用moduleinfo填写基本信息。当使用hub.Module(name=”senta_test”)加载Module时,PaddleHub会自动创建SentaTest的对象并返回。

    1. @moduleinfo(
    2. name="senta_test",
    3. version="1.0.0",
    4. summary="This is a PaddleHub Module. Just for test.",
    5. author="anonymous",
    6. author_email="",
    7. type="nlp/sentiment_analysis",
    8. )
    9. ...

    step 3_3. 执行必要的初始化

    1. def _initialize(self):
    2. # add arg parser
    3. self.parser = argparse.ArgumentParser(
    4. description="Run the senta_test module.",
    5. prog='hub run senta_test',
    6. usage='%(prog)s',
    7. add_help=True)
    8. self.parser.add_argument(
    9. '--input_text', type=str, default=None, help="text to predict")
    10. # load word dict
    11. vocab_path = os.path.join(self.directory, "vocab.list")
    12. self.vocab = load_vocab(vocab_path)

    注意:执行类的初始化不能使用默认的__init__接口,而是应该重载实现_initialize接口。对象默认内置了directory属性,可以直接获取到Module所在路径

    step 3_4. 完善预测逻辑

    1. results = []
    2. for text in texts:
    3. sentiment = "positive"
    4. for word in self.vocab:
    5. if word in text:
    6. break
    7. results.append({"text":text, "sentiment":sentiment})
    8. return results

    step 3_5. 支持命令行调用

    如果希望Module可以支持命令行调用,则需要提供一个经过runnable修饰的接口,接口负责解析传入数据并进行预测,将结果返回。

    如果不需要提供命令行预测功能,则可以不实现该接口,PaddleHub在用命令行执行时,会自动发现该Module不支持命令行方式,并给出提示。

    1. @runnable
    2. def run_cmd(self, argvs):
    3. args = self.parser.parse_args(argvs)
    4. texts = [args.input_text]
    5. return self.sentiment_classify(texts)

    step 3_6. 支持serving调用

    如果希望Module可以支持PaddleHub Serving部署预测服务,则需要提供一个经过serving修饰的接口,接口负责解析传入数据并进行预测,将结果返回。

    如果不需要提供PaddleHub Serving部署预测服务,则可以不需要加上serving修饰。

    完整代码

    完成Module编写后,我们可以通过以下方式测试该Module

    将Module安装到本机中,再通过Hub.Module(name=…)加载

    1. hub install senta_test
    1. import paddlehub as hub
    2. senta_test = hub.Module(name="senta_test")
    3. senta_test.sentiment_classify(texts=["这部电影太差劲了"])

    调用方法2

    直接通过Hub.Module(directory=…)加载

    1. import paddlehub as hub
    2. senta_test = hub.Module(directory="senta_test/")
    3. senta_test.sentiment_classify(texts=["这部电影太差劲了"])

    将senta_test作为路径加到环境变量中,直接加载SentaTest对象

    1. export PYTHONPATH=senta_test:$PYTHONPATH

    调用方法4

    将Module安装到本机中,再通过hub run运行

    1. hub run senta_test --input_text "这部电影太差劲了"