起源|Open Source Data Science Tools
翻译|程浩源
Google Colaboratory,简称 “Colab” ,是一个收费的Jupyter notebook云平台。Colab 不仅能够为用户提供 Python 和 R notebooks 的运行环境,而且还容许用户收费共享局部 GPU 和 TPU 资源。
对于负责在 Jupyter Notebook 编程的数据科学家来说,Colab早已成为了默认的运行环境。然而,将 Colab 的算力使用到除 Jupter Notebooks 以外的其余利用,则是一件极其艰难的事。
对于那些想生产模型,并将其带出Notebook阶段的机器学习工程师而言,这样的问题尤为显著。尽管 Notebooks 非常适合用来摸索,但将它与训练过程编入正式流水线的高级MLOps工具一起应用时,成果不佳。
在遇到相似问题后,我决定不让 Colab 的局限性扭转我的工作流程,而是尝试围绕我的工作流程去扭转 Colab!
出于这个起因,明天咱们将探索 Google Colab 的内部结构,并尝试略微扭转 Colab 的内置规定。须要提前申明的是,咱们只是想探索 Colab,不会对 Colab 自身或者它的用户造成任何影响。
1
揭开幕后的机密
Colab 的机密在于它的后端:谷歌服务器为 Colab 提供基础设施反对,让用户能够轻松运行代码。因而,咱们第一步先剖析 Colab 的 API,最简略的办法是查看 Colab 在失常运行期间进行的 API 调用。
首先关上谷歌开发者工具,找到网络(Network)选项,而后运行一段代码,开发者工具开始记录 Colab 收回的每个申请,而后咱们发现了一些乏味的货色。
看上去这个URL(/tun/m/<id>/socket.io)是近程机器上运行的 Jupyter socket 的代理。
如果咱们从 Colab 界面的左窗格关上 Files 窗格(默认显示 /content 目录),就会发现另一个乏味的申请:
这次 JSON 枚举近程主机上的文件做出了响应。这个URL(/tun/m/<id>/api/contents/)仿佛指向提供文件元数据的服务。
双击 Files 窗格里的文件,Colab 就会开始下载文件并且展现文件详细信息。如果单击 /content/sample_data/README.md,则会对 /tun/m/<id>/files/ 发出请求,返回该文件的内容。
很显著,https://colab.research.google...<id>/ 是运行 Colab 实例服务器的反向代理,它提供了 /socket.io 、 /files 和 /api/contents 端点。
让咱们看看是否有任何服务在 Colab 容器实例内运行。Colab 中内置有 lsof 程序,运行 lsof -iTCP -sTCP:LISTEN,列出所有在 TCP 端口上监听网络申请的过程。
看!colab-fileshim、node 和 jupyter-notebook 看起来都值得一探到底。因为咱们曾经应用过Files窗格,所以先看看 colab-fileshim,它有 PID 28,因而查看 /proc 文件系统,查看过程的残缺命令行:
接下来钻研 /usr/local/bin/colab-fileshim.py。讥刺的是,咱们其实能够间接在 Files 窗格做到这一点。这个程序更像是一个无趣的文件服务器,除了服务器自身能够响应 localhost:3453/files (带有文件内容)和 localhost:3453/api/contents (带有 JSON 元数据)。这意味着 Colab 会将这些申请从信道 URL 转发到实例自身的端口3453。
在谷歌开发者工具的网络选项中,咱们能够右键单击,复制 cURL 命令来重现它。例如,这是用于查看 README.md 文件的 cURL 命令:
如果在本地计算机终端上运行此命令,会将该 README 文件的内容打印到咱们的终端,通过一直尝试和纠错,咱们能够缩小大部分标头,只留下如下内容:
x-colab-tunnel 标头外表上是为了避免 XSS 攻打,实际上是为了避免咱们或黑客从惯例浏览器选项收回这些申请。
cookie 标头用于向 Google 提供身份验证,证实咱们能够拜访笔记本实例。因为 cookie 比拟长且难以解决,在本文的其余部分咱们将其存储到 shell 变量 $COLAB_COOKIE 中。
2
胜利1:揭示咱们的服务器
当初,咱们曾经发现了 Colab 的反向代理,看看是否能够用它为传输咱们本人的申请。
咱们能够简略地用本人的服务器替换过程,而不会影响现有的 colab-fileshim.py 服务器!运行 pkill -f colab-fileshim 来终止现有服务器,这样就能够在同一个端口上启动咱们本人的服务器。
上面做一个简短的演示,咱们将启动 Python 默认的 HTTP 服务器,而后在 localhost:3453/files 中提供咱们本人的文件。
瞧!咱们当初能够更改 cURL 命令来下载咱们本人的文件!
留神 Colab 单元中的日志行,能够证实咱们的服务器解决了申请:
遗憾的是,因为须要 x-colab-tunnel: Google 标头,所以咱们无奈从浏览器间接拜访服务器。
3
进一步钻研
持续进行钻研,这次看一下之前发现的另一个乏味的货色,node。如果咱们查看 /proc/7/cmdline,会看到过程正在运行 /datalab/web/app.js。
一旦咱们跳转并浏览该代码,会发现 /datalab/web 蕴含一个相当规范的NodeJS应用程序。除了之前看到的 /socketio/ 路由,它还公开了 /_proxy/{port}/ 路由。这应该让咱们能够从 Colab 实例上的任何端口拜访任何 URL!
启动一个疾速服务器并测试一下。
惋惜咱们并不能从浏览器选项中查看这个 HTML 页面,Colab 回绝代理任何申请,除非设置了 x-colab-tunnel: Google 标头,如果咱们尝试从浏览器拜访这些URL,会看到一个 HTTP 400 客户端谬误页面:
4
胜利2:揭示整个网页
侥幸的是,咱们能够应用谷歌浏览器扩大程序将 HTTP 标头即时插入浏览器申请中。咱们将其设置为在所有申请上发送 x-colab-tunnel: Google 标头:
而后咱们能够在浏览器中启动信道 URL!
5
返回Jupyter Notebook
最初,让咱们看看第三个,也是最初一个乏味的过程,jupyter-notebook,它监听端口 9000。
咱们能够通过拜访 /tun/m/<id>/_proxy/9000 来应用之前的代理和标头,尝试从浏览器间接拜访端口。遗憾的是,呈现了 HTTP 500 服务器谬误页面,而不是 Jupyter 用户界面。
奇怪的是,当咱们从 Colab notebook 自身运行 !curl -i localhost:9000 来诊断这个问题时,依然报错了:
之前 lsof 的输入为咱们提供了一个线索:Jupyter 只监听提供给 Colab 实例的公有 IP,而不是监听 0.0.0.0/:: (所有接口上的所有 IP),这大略是为了防止将 Jupyter 接口裸露给咱们。
谷歌并没有尽全力暗藏接口,因而有一个疾速修复的办法。
为了绕过监听地址的限度,咱们须要创立一个过程来监听所有接口和 IP,并将它取得的所有流量转发到 Jupyter 正在监听的特定 IP 地址。咱们能够装置socket代理工具 socat(Socket Cat) 来做到这一点。应用 socat 将流量在 localhost:9000 和 $HOSTNAME:9000 之间来回转发:
这是一个开始!如果咱们在浏览器中从新加载 URL,咱们会看到局部 Jupyter 用户界面,但显然呈现了问题。
这是因为 Jupyter 设定在域的根目录下拜访(URL门路 /),但咱们的 Colab 信道的门路是 /tun/m/<id>/_proxy/9000,这会弄乱 CSS 和 JS 文件等资源的绝对路径。
目前还没有简略的解决方案,咱们须要一个残缺的(子)域来将流量转发到Jupyter服务器。
6
胜利3:显示Jupyter用户界面
万幸,Colab 有一个荫蔽的端口转发的官网解决方案,它提供了一个残缺的子域!它暗藏得十分好,发现它比发现外部反向代理破费了更长的工夫!
如何应用 Colab 的官网端口转发流量?从左侧边栏中关上 Code Snippets 选项,而后找到 Output Handling 代码段。
单击“查看Source Notebook”,将会看到advanced_outputs.ipynb,这是Colab 高级用户片段,展现了该平台鲜为人知的性能。咱们须要的特定片段能够在“浏览内核上执行的服务器”题目下找到。
咱们能够应用此代码段将 Jupyter 用户界面公开为子域。
当初,咱们能够单击该链接(将 /tree 附加到 URL 来稳住 Jupyter),而后就能够查看功能齐全的 Jupyter UI!
终于,简直实现了所有工作。谷歌仿佛已将官网代理限度为仅GET申请,只容许咱们查看但不能运行Notebooks。
7
结语
祝贺你看到了最初,心愿这对展现你不理解的Colab相干工作原理以及学习逆向工程工具的半结构化办法会有价值。也心愿能激发你更深刻地理解本人每天应用的工具和产品的内部结构!
(本文经受权后编译公布。原文:https://dagshub.com/blog/reve...)
头图源自wir_sind_klein, Pixabay
欢送下载体验 OneFlow v0.8.0 最新版本:https://github.com/Oneflow-In...