为什么你应该关注Amazon SageMaker

by 杨赛

2014年,AWS在re:Invent上发布Lambda服务的时候,很多开发者尚未意识到这个服务能给他们带来怎样的好处。时隔三年,Lambda服务已经成为了“Serverless”和“Function as a Service”开发范式的代表,并且已经承担起为数不少的企业关键业务。可以说,Lambda服务为应用开发领域开辟了一片全新的游戏场地。

在InfoQ编辑看来,AWS CEO Andy Jassy在今年的re:Invent大会上发布的Amazon SageMaker也是一个改写游戏方式的关键标志,而这一次的游戏场地是在人工智能领域(2017年AWS re:Invent的产品发布列表见之前的这篇报道)。

在2017年的今天,阻碍人工智能技术被广泛应用的最主要的门槛是什么?

芯片、框架、算法、数据量?这些领域当然还有很大成长空间,但很难说是当前的最大门槛。有人说,最大的门槛是准确率还不够,尤其是toC领域的自然语言处理这样的场景,机器对人的表达方式的理解还远远达不到可以正常交流的水平。对于这个准确率的问题,每个体验过相关服务的读者应该都有自己的判断。但如果说这个问题为真,那么下一个问题是:为什么在这些领域,准确率提高得还不够快?

用机器学习来解决一个问题是建立在一个假设之上:针对任何一个问题,我们是能够根据固定数量的变量,得到一个足够好的模型,从而对其进行有效的解释与预测的。所以,基于这样的一个假设,那么准确率低的问题,就是一个模型不够好的问题。

模型不够好有很多原因,可能是因为训练数据不够,也可能是因为算法不合适,或者算法的参数没选择到最合适的组合。训练数据不够,就要多采集数据、多存储数据、多清洗数据。算法不合适,可能是因为参数的调试还没做到位,可能因为参数的调试需要耗费太多时间和其他成本所以在一个局部最优解就停下了,也可能是因为使用的框架(引擎)不合适。至于哪个框架更合适,可能需要多试几个框架,乃至于可能当前市面上流行的框架都不合适,需要一个新的框架。

对于以上各种可能的问题来源,Andy Jassy提出了一个也许是更根本的问题:

也许,我们在建模这个层面的人手太少了?

根据InfoQ编辑所了解,目前市面上有一些业务做得很好的大数据公司,他们的技术团队/数据团队有80%的精力都用来做什么工作呢?

数据准备。

剩下的20%精力,又有很大部分是用在部署集群、安装框架、调优这些“杂活儿”上面了。

从当前的客观情况来看,这是把数据分析业务做好的一个基本功。然而从理想世界的角度来看,这样的现状是相当惊人的浪费。AI领域大牛李飞飞,她有多少时间是用在改进框架和算法上,有多少时间是投入到标记那320万张图片上?

这就好比在云计算出现之前,一个开发者想要开发一个应用,可能80%的时间是用在买服务器、安装操作系统、调试数据库、部署扩容备份等等跟开发应用无关的事情上了。现在的数据领域,跟那个年代的应用开发领域其实是非常相似的——一半以上的时间都不是用来产出的。

有些开发者可能还没动手就被这些麻烦事儿吓跑了。坚持在这个领域深耕的数据科学家们,他们的精力也用不到刀刃上。这就是AWS发布SageMaker的立场:让有能力去改进框架和算法的开发者,尽可能少花费精力在那些跟主业无关的事情上。

简单的看一下SageMaker的基本用法——如何训练一个模型。以下内容来自AWS布道师Randall Hunt发布的博客

首先,在AWS的后台新建一个Notebook用来放置你的代码和一些配置信息。新建好的Notebook下面会自带一个叫做sample-notebooks的目录,里面包含了一些预置的算法:

无论是哪种算法,代码大致上是下面这个结构:

    def train(
        channel_input_dirs, hyperparameters, output_data_dir,
        model_dir, num_gpus, hosts, current_host):
        #给训练代码占座
        pass

    def save(model):
        #找个地方保存模型文件
        pass

首先,channel input dirs:训练数据从哪儿来?可以是本地的一个目录,也可以是云端的。自从S3支持对象级别的查询之后,S3在这几年已经变成一个挺流行的Data Lake选项。现在有了新发布的S3 Select,这个Data Lake的查询变得更高效了。而且现在还有了Glacier Select,于是那些冷数据也可以直接被拿来当作训练数据(题外话:Andy Jassy说这两个Select功能是研发了一年的时间做出来的。你怎么看?我真心觉得还挺快的。)

然后,hyperparameters:这一个步骤就是SageMaker的第一个魔法所在了。看看教程中是怎么定义这个hyperparameter的:

    hyperparameters={
        'batch_size': 128,
        'epochs': 50,
        'learning_rate': 0.1,
        'momentum': 0.9
    }

传统来说,这些hyperparameter的初始设置可能对最终的模型质量有很大的影响。比如这个learning rate,如果设置太低,则学习得太慢;如果设置太高,可能压根跑不出来结果。于是乎,数据科学家们不得不一次又一次的试错,一直试错到他们觉得足够好,或者他们觉得足够烦了为止。

SageMaker的第一个魔法就在于这一个步骤的自动化:把试错这件事交给机器来做,直到机器认为足够好了为止——机器可是从来都不会厌烦的。

其余的训练参数定义比较直观,就不多介绍了。要跑训练的时候,假设你要用MXNet这个框架配合一个你写好的cifar10算法,那么你就这么写(点击这里查看AWS提供的sample notebook-cifar10.py文件的详细内容,以及AWS Github账号上的SageMaker Python SDK。这个文件使用了Gluon API。):

    import sagemaker
    from sagemaker.mxnet import MXNet
    m = MXNet("cifar10.py", role=role,
            train_instance_count=4, train_instance_type="ml.p2.xlarge",
            hyperparameters={'batch_size': 128, 'epochs': 50,
                            'learning_rate': 0.1, 'momentum': 0.9})

现在,可以把训练数据丢给它了:

    m.fit("s3://randall-likes-sagemaker/data/gluon-cifar10")

于是你就有了四个P2实例开始帮你跑训练了!当训练跑完的时候,你就有了一个模型m,可以拿来做预测了。至于这四个P2实例,它们会被自动释放,不用去管它们。这是SageMaker的第二个魔法:忘记你的服务器,也不用折腾各种框架的安装部署这些底层工作。SageMaker上的这些框架都是已经优化好的,你自己部署的话,效果多半不会比它更好。预测的执行也仅仅需要下面这一个指令,不需要在主机层面搞东搞西:

    predictor = m.deploy(initial_instance_count=1, instance_type='ml.c4.xlarge')

比如,可以把想要做预测的在线实时数据——比如一张Twitter上的新照片——通过一个Flask App丢过去:

    @app.route('/invocations', methods=["POST"])
    def invoke():
        data = request.get_json(force=True)
        return jsonify(predict.download_and_predict(data['url']))

然后你就可以得到你的预测结果——比如说,这张照片的拍摄地点。

那么你要问了,SageMaker对于数据准备这个最大的“杂活儿”有啥帮助呢?

SageMaker有一个preprocess数据的功能。至于这个功能能做到什么程度,还得试试才知道,详细情况可以参考这个文档。我想,恐怕暂时还不能跟那些专门提供数据准备服务的质量相比,因为这个文档里面同时也推荐了Marketplace上的相关服务

不过,能够节省下创建实例、安装框架、训练试错这些方面的工作,已经是一个很大的进步。现在,开发者只要有一个AWS账号就可以体验SageMaker,而且现在是有两个月的免费额度的,正是尝鲜的最佳时机。AWS的开发者文档网站已经更新了SageMaker的详细说明,可以在此查看。期待看到SageMaker之后的发展情况。