給 IT 團隊的 Potato 伺服器要求
請把本頁轉發給你的 IT 或科研計算團隊。Potato 以單個程序執行,需要可寫磁碟和 HTTPS,並把每條標註儲存在這臺伺服器上。
Potato 是用於標註研究的自託管網路應用。一個 Potato 程序服務一項研究,把所有標註儲存在研究資料夾內的檔案和 SQLite 資料庫裡,並需要在該程序前面放置一個反向代理來提供 HTTPS。預設安裝不會向外部服務傳送任何資料,資料只通過研究配置所開啟的功能離開伺服器。
本頁寫給大學、醫院或公司裡負責執行伺服器的人。想讓別人託管研究的研究人員,可以把本頁原樣發出,同時附上項目資料夾和下一節列出的答案。沒有 IT 團隊時研究人員能走的路線,見把你的 Potato 研究放到網上。
研究團隊需要提供的資訊
研究團隊會發來項目資料夾,研究設計器以 Download project (.zip) 的形式匯出它。資料夾裡有 config.yaml(研究的配置)以及配置中提到的資料檔案。除資料夾之外,研究團隊還要回答這些問題:
- 有多少位標註者參加,標註者是用機構賬號登入,還是用研究人員列出的使用者名稱登入?
- 研究何時開始,何時結束?
- 條目或答案中是否含有個人資訊或敏感資訊,研究是依據哪份倫理批准進行的?
- 配置是否使用了會把條目傳送給模型提供商的 AI 功能?
config.yaml中的ai_support、chat_support和solo_mode等塊標誌著這類功能。
軟體
Potato 是基於 Flask 構建的 Python 網路應用。最簡單的安裝方式是已釋出的 Docker 映像 ghcr.io/davidjurgens/potato,為 linux/amd64 和 linux/arm64 構建。映像約 900 MB,在 gunicorn 下執行 Python 3.11,以無特權使用者 potato(uid 1000)執行,監聽 7860 埠。項目資料夾掛載到 /app:
docker run -d --name potato-study --restart unless-stopped \
-p 127.0.0.1:8000:7860 \
-v /srv/potato/my-study:/app \
-e POTATO_SECRET_KEY="$(openssl rand -hex 32)" \
ghcr.io/davidjurgens/potato:2.14.0這條命令只在主機迴環介面的 8000 埠釋出研究,反向代理因此成為唯一的入口。latest 標籤跟隨 Potato 的開發分支,研究應當固定一個版本標籤。POTATO_SECRET_KEY 只生成一次,並儲存這個值,因為每次啟動都換新金鑰會讓每位標註者在每次重啟時退出登入。當 /app 不能被 uid 1000 寫入時,容器會拒絕啟動。請用 --user "$(id -u):$(id -g)" 執行容器,或者把資料夾交給 uid 1000。映像的標籤和環境變數見在 Docker 中執行 Potato。
不用 Docker 時,在 Python 3.9 或更新版本上用 pip install potato-annotation 從 PyPI 安裝 Potato。備份和單點登入需要加上 hosting 可選依賴,SAML 登入需要 saml 可選依賴,它依賴系統的 libxmlsec1 來構建。potato start config.yaml 執行的是開發伺服器,每次響應之後都會關閉連線。對於通過網際網路工作的標註者,請按生產部署所示在 gunicorn 下執行 Potato,或者在 potato start 前面放一個反向代理。
程序和工作程序數
Potato 把條目池、分配佇列和每位標註者的狀態都放在一個程序的記憶體裡。第二個 gunicorn 工作程序或第二個副本,會拿到這三者各自獨立的一份,把第一個程序已經分配出去的條目再發一遍,並覆蓋第一個程序的儲存。因此,GUNICORN_WORKERS 大於 1 時映像會拒絕啟動。要獲得更高的併發,請把 GUNICORN_THREADS 從預設的 8 調高。Potato 自己的 Docker 文件認為,八個執行緒足以應付典型研究中同時線上的幾十位標註者。要執行多項研究,就執行多個容器,每個容器使用不同的資料夾和埠。
伺服器規模
記憶體隨條目數增長。Potato 的測量顯示,每個條目在記憶體中佔 0.9 到 1.4 KB,在 Potato 的參考資料集上,伺服器使用了約 365 MB。Potato 自己的雲命令 potato deploy 在大多數主機上選擇 1 或 2 個 vCPU、2 GB 記憶體的機器,這是一個合理的起始規格。
磁碟必須持久且可寫,並且要有空間存放資料檔案、條目所含的媒體檔案以及標註。如果容器的磁碟在重啟時被清空,而下文介紹的內建備份又沒有開啟,每一條標註都會丟失。
網路訪問與 HTTPS
通過 nginx、Apache 或 Caddy 這樣的反向代理來暴露 Potato。代理持有 TLS 證書,並把請求轉發到容器的埠。只需要向網際網路開放 443 埠,以及用於重定向和證書續期的 80 埠。反向代理介紹瞭如何在 https://host.example.edu/my-study/ 這樣的 URL 路徑下提供 Potato,方法是帶 X-Forwarded-Prefix 請求頭的 POTATO_PROXY_FIX=1,或者 POTATO_URL_PREFIX。即時智慧體檢視器使用伺服器傳送事件(server-sent events)進行流式傳輸。如果研究使用這些檢視器,請在 /api/ 位置上關閉代理緩衝。
GET /health 不需要認證,伺服器就緒後返回 {"status": "ok"},伺服器仍在載入資料時返回 503。請把負載均衡器或監控檢查指向這個路由。
Potato 預設不需要任何出站網路訪問。標註者的瀏覽器所載入的指令碼、樣式表和字型都來自伺服器本身,氣隙與離線部署列出了 Potato 如何讓預設安裝保持離線。只有配置開啟的功能才需要出站訪問:
- AI 功能會呼叫配置所指定的模型端點,除非該端點是 Ollama 這樣的本地模型伺服器。
- 備份會寫入配置所指定的 Hugging Face 資料集或 S3 儲存桶。
- 單點登入會聯絡身份提供方。
- 遠端資料來源會讀取配置所指定的儲存桶或資料庫。
- 通過 URL 連結到媒體的條目,會讓標註者的瀏覽器從該 URL 獲取媒體。
Potato 寫入的檔案
Potato 把所有內容都寫入研究的資料夾:
| 項目資料夾中的路徑 | 內容 |
|---|---|
<output_annotation_dir>/<username>/user_state.json | 每位標註者的答案,每次儲存都整份重寫 |
user_config.json,位於輸出資料夾旁邊 | 賬號列表,其中的密碼是加鹽的 PBKDF2-SHA256 雜湊 |
project.sqlite、datasets.sqlite | 備忘、編碼本和審閱狀態等項目資料,使用 SQLite 的 WAL 模式 |
admin_api_key.txt | 未設定金鑰時生成的管理員金鑰,只有伺服器的使用者可讀 |
potato.log | 伺服器日誌 |
因此一個目錄就包含整項研究。output_annotation_dir 是 config.yaml 中的一項設定,研究設計器把它的值設為 output。
備份
對項目資料夾做夜間備份,就能涵蓋標註檔案和賬號列表。兩個 SQLite 檔案請用 SQLite 自己的備份命令複製,不要當作普通檔案複製,因為 WAL 模式下的資料庫檔案副本可能已損壞,或者缺少最近的寫入:
sqlite3 /srv/potato/my-study/project.sqlite ".backup /backups/my-study/project.sqlite"Potato 內建的備份每五分鐘把標註輸出和資料庫快照複製到相容 S3 的儲存桶或私有的 Hugging Face 資料集。啟動時,如果磁碟為空,備份會從儲存桶恢復,並且絕不會覆蓋磁碟上已有的標註。下面的塊把副本傳送到大學的物件儲存。把這個塊加入研究的 config.yaml,並在容器的環境中設定 POTATO_S3_ACCESS_KEY_ID 和 POTATO_S3_SECRET_ACCESS_KEY:
backup:
schedule_minutes: 5
restore_on_boot: true
sinks:
- type: s3
bucket: research-backups
prefix: potato/my-study
endpoint_url: https://s3.example.edu已釋出的映像包含備份客戶端。用 pip 安裝則需要 hosting 可選依賴。
登入方式
Potato 支援多種讓標註者登入的方式,在 config.yaml 中設定:
| 方式 | 適合 | 伺服器需要什麼 |
|---|---|---|
| 帶密碼的具名賬號(預設) | 已知的標註者名單 | user_config.users 列出使用者名稱,並設定 allow_all_users: false。Potato 會拒絕不在名單上的人註冊 |
僅使用者名稱(require_password: false) | 低風險任務和課堂練習 | 無需其他條件。使用者名稱名單仍然適用 |
| OAuth 和 OpenID Connect | Google、GitHub 或 Hugging Face 賬號,或者 Microsoft Entra ID、Okta 等任何 OpenID Connect 提供方 | 一個客戶端 ID 和金鑰,以及在提供方處註冊的回呼 URL https://<host>/auth/callback/<provider> |
| SAML 2.0 | Shibboleth、ADFS,以及 Okta 和 Microsoft Entra 中的 SAML 應用 | saml 可選依賴,或使用 --build-arg POTATO_EXTRAS=saml 構建的映像。Potato 在 /saml/metadata 提供服務提供方後設資料,並在 /saml/acs 接收斷言 |
| 來自眾包平臺的連結 | Prolific、SONA、CloudResearch Connect 以及類似平臺 | 指向伺服器的平臺研究 URL |
密碼使用 PBKDF2-SHA256 做雜湊,迭代 100,000 次,每個使用者有獨立的鹽。忘記的密碼通過 Potato 顯示在螢幕上的一次性連結重置,Potato 不傳送任何電子郵件。在終止 TLS 的代理之後,請把 SAML 的 sp_base_url 設為公開地址,否則身份提供方的響應會通不過 Potato 的目標檢查。每種方式的配置見 SSO 與 OAuth、密碼管理和眾包整合。
管理員訪問
/admin 的管理面板顯示進度、一致性和每位標註者的答案,並可下載結果。面板用管理員金鑰開啟。請通過 POTATO_ADMIN_API_KEY 設定金鑰,或者讓 Potato 在首次使用時在項目資料夾中生成 admin_api_key.txt,再通過你所在機構信任的渠道把金鑰交給研究人員。在任何伺服器上,config.yaml 都要保持 debug: false,因為除錯模式會讓看起來像本地發來的請求不用金鑰就能開啟管理頁面,而同一臺機器上的代理可能讓每個請求都看起來像本地請求。
資料保護
Potato 是自託管的,因此標註、賬號列表和條目都留在你執行的伺服器上。Potato 不含任何分析或使用情況上報,預設安裝不會建立任何出站連線。資料只通過網路訪問與 HTTPS下列出的功能離開伺服器,其中每一項都必須由研究的配置開啟並指定目的地。
請對照研究的倫理批准檢查三點:
- 標註檔案以使用者名稱標識每位標註者,所以用電子郵件地址作使用者名稱,會把電子郵件地址放進資料裡。
- 研究中的調查頁面可能收集個人資訊,答案與其他內容一起放在每位標註者各自的檔案裡。
- 當配置把條目傳送給託管的模型提供商時,條目會在該提供商的條款下離開伺服器。
研究結束時,研究團隊從管理面板下載結果。請與團隊商定伺服器上的副本保留多久,並在那個日期之後刪除項目資料夾和所有備份儲存桶。
延伸閱讀
- 在 Docker 中執行 Potato,介紹映像的標籤、環境變數和檔案所有權
- 生產部署,介紹 gunicorn、nginx、Apache 和 Docker Compose
- 反向代理,介紹如何在 URL 路徑下提供 Potato
- 氣隙與離線部署,適用於沒有出站訪問的網路
- 把你的 Potato 研究放到網上,同一過程中研究人員這一側