Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践Streamlit & Flask - AIプロジェクトをいい感じにする技術 / Service development with Streamlit and Flask

実践Streamlit & Flask - AIプロジェクトをいい感じにする技術 / Service development with Streamlit and Flask

PyCon JP 2021「実践Streamlit & Flask - AIプロジェクトのプロトタイピングから本番運用までをいい感じにするPythonicなやりかた」登壇資料

# 「AIオオタニサン本塁打予測」のサンプルコード

https://github.com/Shinichi-Nakagawa/streamlit-sample-ohtani-san

# 参考文献

## JX通信社エンジニアブログ

- https://tech.jxpress.net/entry/data-app-for-streamlit
- https://tech.jxpress.net/entry/vaccine-gae
- https://tech.jxpress.net/entry/ogp-generator

## Lean Baseball

- https://shinyorke.hatenablog.com/entry/flask-and-gae-and-github-actions
- https://shinyorke.hatenablog.com/entry/engineer-and-datascientist
- https://shinyorke.hatenablog.com/entry/jupyter-to-streamlit

## Agile Manifest

https://agilemanifesto.org/iso/ja/manifesto.html

## 仕事ではじめる機械学習 第2版

https://www.oreilly.co.jp/books/9784873119472/

Shinichi Nakagawa

October 16, 2021
Tweet

More Decks by Shinichi Nakagawa

Other Decks in Technology

Transcript

  1. ࣮ફStreamlit & Flask
    Shinichi Nakagawa(@shinyorke)


    PyCon JP 2021 10/16
    AIϓϩδΣΫτͷϓϩτλΠϐϯά͔Βຊ൪ӡ༻·ͰΛ͍͍ײ͡ʹ͢ΔPythonicͳ΍Γ͔ͨ


    View Slide

  2. ͜ͷ͓࿩͸
    • ʮAIͰ͍͍ײ͡ʹͯ͘͠Εʯʮ࠶དྷ݄ʹ͸ϓϩμΫτ͕ཉ͍͠ʯ

    ͱ͔ݴΘΕͨΒɺ͋ͳͨͳΒͲ͏͠·͔͢?΋ͪΖΜ࢓ࣄͰ.


    • ͔͠΋ͦͷϓϩμΫτ͕͋Δ೔ಥવTVʹग़ΔʢͦΕ΋શࠃ۠ʣ

    …ͬͯɺෛՙରࡦͱ͔τϥϒϧ͕ා͍Ͱ͢ΑͶ😇


    • ͱ͔͍͏࣮࿩ʹج͖ͮɺࢲʢshinyorkeʣ͕Python࢖͍ͱͯ͠

    ͲͷΑ͏ʹPythonicʹղܾ͔ͨ͠?ͱ͍͏ͷ͕͜ͷൃදʹͳΓ·͢

    View Slide

  3. ͜ͷ࿩ͷείʔϓʢ࿩͢͜ͱ&ର৅ऀʣ
    • JX௨৴ࣾʮNewsDigestʯͷظؒݶఆίϯςϯπͱͯ͠ग़͍ͯͨ͠

    ʮAIϫΫνϯ઀छ༧ଌʯͷ։ൃ͔Βӡ༻ͷ࣮࿩Λݩʹ


    • Streamlit΍FlaskͳͲΛ࢖ͬͯ೗ԿʹPython࢖͍Β͘͠΍͔ͬͨ?Λ࿩͠·͢


    • ͳ͓, طʹAIϫΫνϯ઀छ༧ଌͷαʔϏε͸ऴ͍ྃͯ͠ΔͨΊ,

    αϯϓϧͱͳΔΑ͏ͳΞϓϦΛ࡞͖ͬͯ·ͨ͠&ͦΕΛݩʹղઆ


    • WebΞϓϦ։ൃऀ͔ΒσʔλαΠΤϯςΟετ·Ͱָ͓͠Έ͍͚ͨͩ·͢
    ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ

    View Slide

  4. Who am I ?ʢ͓લ୭Αʣ
    • Shinichi Nakagawaʢத઒ ৳Ұʣ


    • େ఍ͷSNSͰʮshinyorkeʢ͠ΜΑʔ͘ʣʯͱ໊৐͍ͬͯ·͢


    • Software Engineer & Data ScientistʢؚΉ⽁ʣ


    • ݩɾJX௨৴ࣾγχΞΤϯδχΞ

    ※9݄·Ͱ, 10݄͔Βస৬͠·ͨ͠


    • #Python #DataScience #Baseball⚾ #SABRmetrics

    View Slide

  5. ࠓ೔ͷ͓౔࢈
    • AIϓϩδΣΫτΛ੒ޭͤ͞ΔͨΊʹඞཁͳߟ͑ํͱελϯε


    • PoCʢ֓೦࣮ূʣͷ͸ͳ͠ - StreamlitͰ͍͍ײ͡ʹ΍Δ


    • ϓϩμΫτ։ൃ͔Βϩʔϯν, ӡ༻·ͰΛPythonicʹ΍Δ


    • ͪΐͬͱͨ͠খωλ - ΞΠΩϟονը૾ੜ੒ͱCIपΓ


    ͜ΕΒΛJX௨৴ࣾ࣌୅ͷ࢓ࣄʢͷެ։৘ใʣ͓Αͼݸਓ։ൃͨ͠಺༰͔Β঺հ

    View Slide

  6. ຊ೔࿩͞ͳ͍͜ͱʢ౴͑ͳ͍͜ͱʣ
    • ݱ৬ͷ࿩ʢͲ͜Ͱಇ͍͍ͯΔɾ࢓ࣄԿͯ͠Δͱ͔ʣ

    ask the speakerؚΊͯҰ੾࿩͠·ͤΜ🙇ʢḨࡧ΋φγͰʣ


    • લ৬ʢJX௨৴ࣾʣͷࠓͷ࿩ɾ࠾༻ͷ࿩ɾެ։͞Εͯͳ͍৘ใ

    JX௨৴ࣾͷࣄ͸εϙϯαʔϒʔεͰதͷਓʹฉ͍ͯʂ

    ͍͍࿩Λͯ͘͠ΕΔͱࢥ͏ͷͰ👍


    • ͦͷଞ, ࢲʢshinyorkeʣ͕ෆద੾ͱ൑அͨ͠಺༰

    View Slide

  7. AIϓϩδΣΫτʹඞཁͳελϯε
    • ෆ࣮֬ͳϓϩδΣΫτ͸Agileͳ΍ΓํͰղܾ͍ͯ͘͠


    • σʔλαΠΤϯςΟετͱΤϯδχΞ͸ҧ͏ੜଶܥͷੜ͖෺

    νʔϜϫʔΫΛେ੾ʹʂ


    ͜ͷൃදͰҰ؏͍ͯ͠Δߟ͑ํɾେ੾ʹͯ͠ΔࣄͷએݴͰ͢

    ʢҟ࿦͸ೝΊΔʣ

    View Slide

  8. ෆ࣮֬ੑͱ޲͖߹͏ͨΊͷAgile
    • ෆ࣮֬ੑ͕ߴ͍, AIɾػցֶशͳϓϩδΣΫτͦ͜

    ʮಈ͘ιϑτ΢ΣΞʯΛݩʹ։ൃ͢ΔΞϓϩʔν͕େࣄ


    • PoCͱ͸͍͑, ͳΔ΂͘ຊ൪͕ΠϝʔδͰ͖Δಈ͘

    ΞϓϦέʔγϣϯͰձ࿩͢Δͷ͕͍͍ͱࢥ͏ʢೝࣝҧ͍ͷ๷ࢭʣ


    • Ұํ, खΛൈ͚Δॴ͸खΛൈ͖·͘Δ΂͖ʢ㲈࡞Βͳ͍ɾ΍Βͳ͍ʣ

    υΩϡϝϯτ΍ςετΑΓٞ࿦Ͱ͖ΔΞϓϦ͕ඞཁͳ࣌΋͋Δ

    View Slide

  9. ΞδϟΠϧϚχϑΣετͦͷ΋ͷͰ͢
    ࢲͨͪ͸ɺιϑτ΢ΣΞ։ൃͷ࣮ફ
    ͋Δ͍͸࣮ફΛखॿ͚Λ͢Δ׆ಈΛ௨ͯ͡ɺ
    ΑΓΑ͍։ൃํ๏Λݟ͚ͭͩͦ͏ͱ͍ͯ͠Δɻ
    ͜ͷ׆ಈΛ௨ͯ͠ɺࢲͨͪ͸ҎԼͷՁ஋ʹࢸͬͨɻ
    ϓϩηε΍πʔϧΑΓ΋ݸਓͱର࿩Λɺ
    แׅతͳυΩϡϝϯτΑΓ΋ಈ͘ιϑτ΢ΣΞΛɺ
    ܖ໿ަবΑΓ΋ސ٬ͱͷڠௐΛɺ
    ܭըʹै͏͜ͱΑΓ΋มԽ΁ͷରԠΛɺ
    Ձ஋ͱ͢Δɻ͢ͳΘͪɺࠨهͷ͜ͱ͕ΒʹՁ஋͕͋Δ͜ͱΛ
    ೝΊͳ͕Β΋ɺࢲͨͪ͸ӈهͷ͜ͱ͕ΒʹΑΓՁ஋Λ͓͘ɻ
    https://agilemanifesto.org/iso/ja/manifesto.html

    View Slide

  10. େࣄʹ͢ΔϙΠϯτ͕ͪΌ͏Μ΍Ͱ, ͱཧղͯ͠΋Β͑Ε͹.


    https://shinyorke.hatenablog.com/entry/ml-ops-and-engineering
    ΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍

    View Slide

  11. ࣗ෼ͳΒͲ͏͢Δ͔🤔ɹ˞࣮ࡍ΍ͬͨ͜ͱ
    • ΤϯδχΞ΋σʔλαΠΤϯςΟετ΋

    ʮͦͷ৔Ͱಈ͘ΞϓϦέʔγϣϯʯΛϕʔεʹձ࿩Λ͢Δ


    • ࣮ݧίʔυͱϓϩμΫτίʔυͷҠߦΛεϜʔζʹ΍Δ࢓૊Έ


    • ΤϯδχΞͱσʔλαΠΤϯςΟετ͸

    ʮҧ͏ੜଶܥͰੜ͖͍ͯΔϓϩϑΣογϣφϧͰ͋Δʯ

    ͱೝࣝʢ֮ࣗʣ͠, ૬खΛϦεϖΫτ͢Δʢ͓ؾ࣋ͪͱͯ͠ʣ

    View Slide

  12. Python࢖͍͕Pythonicʹ΍Δʹ͸🤔
    • PoCɾϓϩτλΠϐϯάͷखஈͱͯ͠ͷStreamlit


    • ʮͦͷ৔Ͱಈ͘ΞϓϦέʔγϣϯʯΛͬ͞͞ͱखʹೖΕΔ


    • νʔϜϝΠτͱձ࿩͢Δखஈ΋͍͍ײ͡ʹ͢Δ


    • PoC͔Βຊ൪ϓϩμΫτ΁ͷڮ౉͠ͱͯ͠ͷPythonͳWeb APIʢࠓճ͸Flaskʣ


    • ʮ࣮ݧίʔυͱϓϩμΫτίʔυͷҠߦΛεϜʔζʹʯΛલఏʹ։ൃ


    • ڮ౉͠ʹඞཁͳ޻෉Λఴ͑Δʢύοέʔδߏ੒͓ΑͼςετɾCIͷ४උʣ

    View Slide

  13. ???ʮ࣮ࡍͲ͏΍ͬͯ΍ΔΜ͡Ό🤔ʯ


    ͱ͍͏࿩Λ͜Ε͔Β΍Γ·͢

    View Slide

  14. PoCʢ֓೦࣮ূʣͷ͸ͳ͠ - StreamlitͰ͍͍ײ͡ʹ΍Δ
    StreamlitΛ࢖ͬͨϓϩτλΠϐϯάͱਓ΁ͷݟͤํʢັͤํʣ

    View Slide

  15. ࠓճͷ͓୊ʮAIΦΦλχαϯຊྥଧ༧ଌʯ
    ౤खͷϘʔϧʢར͖࿹ɾٿ଎ɾมԽٿʣ͔ΒʮΦΦλχαϯ͕ϗʔϜϥϯΛଧͯΔ͔ʁʯΛ༧ଌ͢Δ, ࡶͳAIαʔϏεͷ։ൃࣄྫΛݩʹ঺հ͠·͢

    ※ʲิ଍ʳ͜ͷൃදͷͨΊʹ։ൃͨ͠΋ͷͰ͢&ͿͬͪΌ͚ਫ਼౓͸βϧͰ͢ʢ͓΋ͪΌͰ͢ɺຊؾʹ͠ͳ͍ͰͶʣ

    View Slide

  16. ਏ͘ͳ͍Streamlitɹ - ͻͱ·ͣೖ໳͠Α͏
    ㅟ ㅟ ㅟ ㅟ
    • ͻͱ·ͣಈ͔͢


    • ͻͱ·ͣݟͤΔʢProxy͢ΔɾΫϥ΢υʹUp͢Δʣ


    • WebΞϓϦέʔγϣϯͬΆ͘࢓্͛Δ

    View Slide

  17. ͻͱ·ͣಈ͔͢
    $ pip install streamli
    t

    $ streamlit hello
    • ಋೖ͸ී௨ʹpip installͰ͍͚·͢


    • ʮstreamlit helloʯͱ͔ଧͭͱ, αϯϓϧ্ཱ͕͕ͪΔ


    • ↑ͷαϯϓϧͷίʔυ΋͙͢ಡΊ·͢, ͜ΕͰงғؾ͸௫ΊΔ


    https://streamlit.io/

    View Slide

  18. ͻͱ·ͣݟͤΔ - ϩʔΧϧ؀ڥ͔Β
    $ ngrok http 8501
    • streamlitͷਖ਼ମ͸WebΞϓϦέʔγϣϯͳͷͰ, Կ͔͠ΒͷखஈͰProxyͯ͋͛͠Ε͹ྑ͍


    • ࣗ෼ͷϚγϯʢϩʔΧϧʣͰಈ͔͢ͳΒngrok౳ͰProxyͰߦ͚Δ

    ʢࣾ಺ͷηΩϡϦςΟϧʔϧͱ͔Ͱ໰୊ͳ͚Ε͹ʣ


    • ײ֮తʹ͸Slack Botͷ։ൃʹ͍ۙʢngrokͰProxyͬͯΑ͘΍ΔͰ͠ΐʣ

    View Slide

  19. ϩʔΧϧ͡Όͪΐͬͱ 🤔ͬͯ࣌͸
    • ࣗલͷ؀ڥͰ΍Δ


    • ContainerʢDockerʣ΍Virtual MaschineతͳIaaSʢGCE΍AWS EC2ͳͲʣΛ४උ


    • ४උͨ͠؀ڥʹσϓϩΠ


    • StreamlitͷΫϥ΢υαʔϏεΛ࢖͏


    • https://streamlit.io/cloud


    • શੈքʹࡽͯ͠OKͳΒ͜ΕͰ΋ྑ͍͔΋ʢͨͩ͠βతͳαʔϏεͬΆ͍ʣ

    View Slide

  20. AIΦΦλχαϯͷdeployϑϩʔ
    mainϒϥϯνʹpushͨ͠த਎͕Ϗϧυ͞ΕͯCloud Runʹdeploy͞ΕΔ࢓૊Έ


    ޙͷεϥΠυͰܰ͘ղઆ͠·͢

    View Slide

  21. WebΞϓϦέʔγϣϯͱͯ͠࢓্͛Δ
    • HTMLͰॻ͘Α͏ͳϨϕϧͷUIίϯϙʔωϯτ͸αΫοͱॻ͚·͢


    • Form෦඼ఔ౓͸Pythonίʔυ1, 2ߦͰ͍͚Δ


    • άϥϑ΍ՄࢹԽ͸PythonͰ࢖͍׳ΕͨϥΠϒϥϦ͕ͦͷ··࢖͑·͢


    • matplotlib


    • plotly


    • etc…


    • ͋Δఔ౓ͷϖʔδભҠʹ΋ରԠ

    View Slide

  22. ʲྫʳαΠυόʔʹFormΛදࣔ͢Δ
    import streamlit as s
    t

    # PITCH_TYPES, THROWS͸DictionaryͰ͢
    from interfaces.view.label import PITCH_TYPES, THROW
    S

    st.sidebar.markdown
    (

    ""
    "

    # ϘʔϧΛܾΊΔ
    ""
    "

    )

    # valueΛselectboxͷϥϕϧʹ͍ͨ࣌͠͸lambdaؔ਺ΛڬΉ
    p_throw = st.sidebar.selectbox
    (

    "ར͖࿹"
    ,

    THROWS.keys()
    ,

    format_func=lambda x: THROWS[x
    ]

    )

    pitch_speed = st.sidebar.slider
    (

    'ٿ଎ʢkm/hʣ', 70, 170, 150,
    5

    )

    pitch_type = st.sidebar.selectbox
    (

    "ٿछ"
    ,

    PITCH_TYPES.keys()
    ,

    format_func=lambda x: PITCH_TYPES[x
    ]

    )

    View Slide

  23. ͜͜·ͰͰ͖Δͱ
    • νʔϜϝΠτ, Ғ͍ਓͱ͍ͬͨεςʔΫϗϧμʔʹ੒ՌΛ

    ݟͤΔ͜ͱ͕͍͍ײ͡ʹͰ͖Δ


    • Jupyter notebook΍ColabͰݟͤΔҎ্ʹΞϓϦͬΆ͍

    UIͱಈ͖ͰϓϩτλΠϓΛ։ൃͰ͖Δ


    • ͜͜·Ͱ͍͚͹, ٞ࿦͠ͳ͕ΒϑΟʔυόοΫ΋Βͬͯ

    ख௚͠Ͱ͖ΔͰ͠ΐ͏👍

    View Slide

  24. ϓϩτλΠϐϯά͔Β։ൃ΁ͷότϯ౉͠
    σʔλαΠΤϯςΟετ͕ॻ͍ͨίʔυ͸͍ͣΕΤϯδχΞ͕ղऍ͠ϓϩμΫτίʔυʹͳΔ


    ͦͷલʹͪΐͬͱͨ͠ʮͻͱ޻෉ʯΛΤϯδχΞͳਓͱҰॹʹ΍ͬͯΈΔͱ͍͍Ͱ͠ΐ͏👍

    View Slide

  25. ϓϩτλΠϓͱίʔυΛ͍͍ײ͡ʹ౉͢
    • ίʔυΛ෼ׂ͢Δ


    • ςετΛॻ͘


    • ʢՄೳͳΒʣϦϑΝΫλϦϯάΛ͢Δ

    View Slide

  26. ίʔυΛ෼ׂ͢Δ
    • Jupyter notebook΍StreamlitͰॻ͍ͨίʔυΛҙຯ͋Δ୯Ґʹ෼͚Δ


    • σʔλͷॲཧʢೖग़ྗ, લॲཧʣ


    • Ϟσϧͷॲཧʢֶशɾ༧ଌʣ


    • ༧ଌ݁Ռͷ֬ೝɾςετ


    • ී௨ͷpythonεΫϦϓτͰߏΘͳ͍ʢΦϒδΣΫτࢦ޲͡Όͳ͍͍ͯ͘ʣ

    ଞͷਓʢίʔυΛ΋Βͬͨਓʣ͕ࣗྗͰಈ͔ͤΔ͜ͱ͕ॏཁ

    View Slide

  27. ςετΛॻ͘
    • READMEͳςΩετʹՃ͑ͯςετΛॻ͘ɾಈ͔ͤΔΑ͏ʹ͢Δ


    • ࡞ͬͨϞσϧͷ࢓༷Λ࠷௿ݶ୲อͰ͖Ε͹OK


    • ඪ४Ϟδϡʔϧͷunittest, αʔυύʔςΟʔͳΒpytest͋ͨΓ

    Ͱॻ͍ͯಈ͔ͤΔͱྑ͍Ͱ͠ΐ͏


    • ϓϩμΫτίʔυʹ͢Δͱ͖, ͏͔ͬΓյ͢ɾಈ͔ͳ͍తͳ

    ࣄނΛ๷͙ͨΊʹ΋ઈରʹઈରʹ΍ͬͨ΄͏͕͍͍

    View Slide

  28. ϦϑΝΫλϦϯάʢ౒ྗ໨ඪʣ
    • ίʔυ෼ׂͱςετ͕͋Ε͹, ࢓༷Λม͑ͳ͍ʢյ͞ͳ͍ʣ༷,

    ؾΛ͚ͭͳ͕Β͖Ε͍ͳίʔυʹॻ͖௚͢͜ͱ͕Ͱ͖Δ


    • ͦ͏, ͍ΘΏΔʮϦϑΝΫλϦϯάʯ͕Ͱ͖Δʂ


    • ϚετͰ͸ͳ͍͕, ϓϩμΫτίʔυʹ͢Δͱ͖ʹԿ͔͠Β΍Δ

    ͱࢥΘΕΔͷͰ, ڞಉ࡞ۀͱͯ͜͠ͷλΠϛϯάͰ΍Δͷ͸ΞϦ

    View Slide

  29. ʲਤʳϓϩτλΠϓͱϓϩμΫτͷύοέʔδߏ੒
    ࠨ͕StreamlitͷϓϩτλΠϓ, ӈ͕ͦͷޙAPIԽͨ͠ϞϊͦΕͧΕͷύοέʔδߏ੒

    ׬શʹҰॹ͡Όͳͯ͘΋, ϧʔϧͷҰ؏ੑΛ΋ͨͤΔ͜ͱͰίϛϡχέʔγϣϯ͠΍͘͢ͳΔ͸ͣ

    View Slide

  30. ʮίʔυ෼ׂʯʮςετʯͱ͍͏όέπϦϨʔ
    …͕, ্ख͘ճΔΑ͏ʹ͢ΔͨΊʹ͸?ͱߟ͑ͯίʔυΛॻ͘ͱ͍͍ͱࢥ͏


    ಉ͡Python࢖͍ͳΒ͜ͷลͰίϛϡχέʔγϣϯऔΕΔͱࢥ͍·͢͠

    View Slide

  31. ϓϩμΫτ։ൃ͔Βϩʔϯν, ӡ༻·ͰΛPythonicʹ΍Δ
    ϓϩτλΠϓ͔ΒຊϓϩμΫτͷ։ൃ, ͦͯ͠TV๒ʹଧͪউͭ·Ͱ

    View Slide

  32. ࠷ऴతͳϓϩμΫτ͕͜͏ͳͬͨͱԾఆͯ͠
    ϑϩϯτΤϯυͱόοΫΤϯυ͕෼͔ΕΔࠓͲ͖ͷߏ੒Ͱ࡞Γ·͢ʂ͍ͬͯ͏ମͰ


    ޙ൒ύʔτ͸ʮJSONΛฦ͢RESTfulͳAPIʯͷ෦෼Λத৺ʹ࿩͠·͢
    ϑϩϯτΤϯυ όοΫΤϯυ

    View Slide

  33. ͜͏͍͏ΞʔΩςΫνϟʹͳͬͨͱ͠·͢
    Google App EngineͰ͸͡ΊΔ, Β͘Β͘TV๒ରࡦ - AIϫΫνϯ઀छ༧ଌͷ෣୆ཪ


    https://tech.jxpress.net/entry/vaccine-gae

    View Slide

  34. FlaskͰAPIԽ͔ͯ͠ΒͷGCP΁ͷdeploy
    • ΞʔΩςΫνϟΛߟ͑Δ - GCPͷ͹͍͋


    • CloudͰϑϧϚωʔδυͳαʔϏεΛલఏͱͨ͠Flaskͷ࢖͍ํ


    • GAEͰͷߴෛՙରࡦ

    View Slide

  35. ΞʔΩςΫνϟબͼͷࡶͳجຊ
    • εέʔϦϯάͷཁ݅


    • ϦΫΤετ਺ɾτϥϑΟοΫʹ೾͕͋Δ࣌͸App EngineΈ͍ͨͳϑϧϚωʔδυͳαʔϏε͕͍͍ײ͡


    • ϦΫΤετ਺͕ൺֱత҆ఆʢ㲈αʔόʔͷ୆਺͕ܾ·ͬͯΔʣͦ͠͏ͳ࣌͸ଞͷཁ݅࣍ୈͰࣗલͰαʔόʔ؅ཧ͍͍͔ͯ͠΋?


    • ࢖͍͍ͨϥΠϒϥϦɾFramework͕࢖͑Δ؀ڥ͔Ͳ͏͔


    • ඪ४తͳϥΠϒϥϦɾFrameworkͰࡁΉ৔߹͸ϑϧϚωʔδυͳΫϥ΢υαʔϏε͕ಘҙͳͷͰͦͬͪʹدͤͨ΄͏͕޾ͤ.


    • ͨͩ͠, ϑϧϚωʔδυͳΫϥ΢υαʔϏε͸ϥΠϒϥϦɾFrameworkʹ͋Δఔ౓੍໿͕͋ΔͷͰ஫ҙ͕ඞཁ, ಛघͳཁ͕݅͋Δ࣌͸ಛʹ.


    • ྉۚ💰


    • ϑϧϚωʔδυͳαʔϏεͱͦ͏͡Όͳ͍ͷ, Ͳ͕ͬͪඒຯ͍͔͠ݟۃΊΔʢଛӹ෼ذ఺΋ؚΊͯʣ


    • Ծ૝ϚγϯܥͷαʔϏεͳΒ֬໿ར༻ׂҾʢϦβʔϒυΠϯελϯεͳͲʣΛ࢖͑ΔαʔϏεʹ͢Δ͜ͱ΋ݕ౼

    View Slide

  36. Google App EngineʢGAEʣΛ૝ఆͨ͠FlaskΞϓϦ։ൃ
    AIΦΦλχαϯຊྥଧ༧ଌ͓ΑͼJX௨৴ࣾͷʮAIϫΫνϯ઀छ༧ଌʯ͸GAE + FlaskͰ΍Γ·ͨ͠

    ͦͷ࣌ͷצॴΛ঺հ͠·͢

    View Slide

  37. ͻͱ·ͣಈ͔͢ - ελϯμʔυ؀ڥฤ
    • ͸͡ΊͯGAEΛ৮Δʢorٱ͠ͿΓʹ৮Δʣํ͸Google CloudͷΫΠοΫελʔτΛࢀߟʹ΍Δͱ
    ྑ͍Ͱ͠ΐ͏, ࣸܦͯ͠ਅࣅΔͷ͕ͪΐ͏ͲΑ͍͔΋.


    • https://cloud.google.com/appengine/docs/standard/python3/quickstart?hl=ja


    • ্هΛ௨͠Ͱ΍ΔͱFlask੡ͷhello world͕ര஀, ࢓૊Έ΋ཧղͰ͖Δ͸ͣ.


    • ͋ͱ͸࡞Γ͍ͨϞϊͷ࢓༷ʹ߹ΘͤͯFlaskͷίʔυΛ͍͡Ε͹OK


    • ྫ͑͹RESTfulʹ͢ΔͳΒResponseΛJSONʹม͑Δͱ͔


    • FastAPIͳͲ, ଞͷFWΛ࢖͏࣌͸ͦ͜ʹ߹Θͤͯ࡞Γ௚ͤ͹

    View Slide

  38. ϥΠϒϥϦ΁ͷґଘΛݮΒ͢
    # AIΦΦλχαϯຊྥଧ༧ଌͷύοέʔδߏ੒ʢΠϝʔδʣ
    app
    /

    !"" entities
    /

    !"" interfaces/ # FlaskҎ֎ͷαʔυύʔςΟʔɾϥΠϒϥϦΛimportͯ͠OKͳॴ
    !"" tests
    /

    # !"" dataset
    /

    # !"" interfaces
    /

    # $"" usecase
    /

    !"" usecase
    /

    main.py # Flaskʹґଘͯ͠OKͳͱ͜Ζ
    • αʔυύʔςΟʔͷϥΠϒϥϦɾFramework΁ͷґଘ͸ہॴతʹ͢Δͱྑ͍


    • Կ͔ͷ౎߹Ͱ࡞Γม͑Δʢྫ͑͹GAEҎ֎Ͱಈ͔͢ʣΈ͍ͨͳ࣌ʹมߋՕॴ͕গͳͯ͘ࡁΉ


    • ΫϦʔϯɾΞʔΩςΫνϟͳͲ͕ͦͷΑ͏ͳߟ͑ํͩͬͨΓ͢ΔͷͰਅࣅ͢Δͱ͍͍͔΋͠Εͳ͍

    View Slide

  39. ͱͭͥΜͷߴτϥϑΟοΫରࡦ📺
    ໌೔TVʹग़·͢ʂʂʂ...ͬͯͳͬͨΒتͼͱෆ͕҆͋Γ·͢ΑͶ


    ͦ͜ʹରͯ͠Ͳ͏΍ͬͯ΍͍͔ͬͯͬͨ?

    View Slide

  40. ݩωλʢJX௨৴ࣾΤϯδχΞϒϩάʣ
    Google App EngineͰ͸͡ΊΔ, Β͘Β͘TV๒ରࡦ - AIϫΫνϯ઀छ༧ଌͷ෣୆ཪ


    https://tech.jxpress.net/entry/vaccine-gae

    View Slide

  41. ߴෛՙରࡦʢapp.yamlهड़ྫʣ
    runtime: python3
    9

    automatic_scaling
    :

    max_instances: 33 # ࠷େͷΠϯελϯε਺ʢ͜ΕҎ্૿͑ͳ͍ʣ
    min_instances: 4 # ࠷খͷΠϯελϯε਺ʢ͜ΕҎ্ݮΒͳ͍ʣ
    • app.yamlͷΦϓγϣϯΛ͍ͬͯ͡deployͨ͠Β͍͍ײ͡ʹ͍͚·͢ʢ্هͷྫ͸ελϯμʔυ؀ڥʣ


    • TVʹग़Δ, SNSͰόζΔ౳͕༧૝͞ΕΔ࣌͸ࣄલʹύϥϝʔλΛ͍ͬͯ͡σϓϩΠͯ͠ղܾ

    ͪͳΈʹ૿͑ͨΠϯελϯε͸app.yamlΛ௚ͯ͠࠶σϓϩΠ or GCPͷίϯιʔϧͰखಈͰফ͢౳ͰରԠͰ͖·͢


    • min_instancesΛ0ʹͨ͠ΒʮϦΫΤετ͕͖ͨΒ্ཱͪ͛ΔʯΈ͍ͨͳײ͡ʹ

    ʢϨεϙϯε͕དྷΔ·Ͱ࣌ؒ͸͔͔Δ͕ྉۚ͸અ໿Ͱ͖Δʣ


    • max_instancesΛ0ʹͨ͠Βύϥϝʔλ͕ແޮʹͳΓ·͢…͕͓͢͢Ί͸͠·ͤΜ

    ࣄ্࣮࠷େ஋Λఆٛ͢Δ͜ͱʹͳΔͨΊʢ㲈ͳʹ͔ͷΞΫγσϯτͰΠϯελϯε͕૿͑Δʣ

    View Slide

  42. ࣮ࡍ΍ͬͯΈͨײ૝
    • JX௨৴ࣾ࣌୅ͷ࢓ࣄʮAIϫΫνϯ઀छ༧ଌʯͰ͸,

    TVͳͲ͍͔ͭ͘ͷཧ༝Ͱߴෛՙ͕༧૝͞ΕΔ࣌ʹapp.yamlΛมߋͯ͠ରԠ


    • αʔϏεͷ฼ମͱͳΔNewsDigestʢͪ͜Β͸ผͷํ๏Ͱߴෛՙରࡦʣ

    ؚΊ, αʔϏε͸ͳΜͯ͜ͱແ҆͘ఆՔಇͯͨ͠👍


    • App Engineͷ͓͔͛ͰWBS΋News ZERO΋Ί͟·͠ςϨϏͷ

    ΞΫηε͔Β଱͑, Ϣʔβʔ͞ΜʹମݧΛఏڙͰ͖·ͨ͠ʢײँʣ

    View Slide

  43. ʲখᄉʳಈతͳը૾ੜ੒ͱCIपΓ
    ϓϩτλΠϓ͔ΒຊϓϩμΫτͷ։ൃ, ͦͯ͠TV๒ʹଧͪউͭ·Ͱ

    View Slide

  44. αʔόʔαΠυͰαΫοͱը૾Λͭ͘Δ
    # ࣮ࡍͷίʔυͱ͸ҟͳΓ·͢ʢ͋͘·ͰαϯϓϧͰ͢ʣ
    import cairosv
    g

    def convert_ogp(area: str, age: int, period: str)
    :

    # Կ͔͠Βͷํ๏ͰSVGϑΥʔϚοτͳςΩετΛೖख
    ogp_context = 'TODO: ͜͜ʹSVGͷத਎͕ೖΔ
    '

    # TemporaryFileͱͯ͠ॻ͖ग़ͯ͠ޙbyteͰ΋Β͏
    with NamedTemporaryFile('w') as f
    :

    f.write(ogp_context
    )

    f.flush(
    )

    image_bytes = svg2png(url=f.name, write_to=None
    )

    return image_byte
    s

    image = convert_ogp('౦ژ౎', 40, '10݄Լ०ʙ2্݄०')
    ↑͜͏͍͏ը૾Λͭ͘Δํ๏ʢαϯϓϧίʔυ→ʣ


    • σβΠϯΛSVGͰىͯ͜͠cairosvgͰpngʹม׵

    SVGΛJinja2ͱ͔ͰςϯϓϨʹͨ͠Βಈతʹߦ͚Δ


    • ಈ͔͢؀ڥ͸஫ҙ͕ඞཁ. GAEͰϑΥϯτͷΠϯετʔϧ͸Ͱ͖ͳ͍.

    ͦ͜ͰϋϚͬͨͷͰDockerԽͯ͠Cloud RunͰӡ༻͠·ͨ͠.

    ৄ͘͠͸, https://tech.jxpress.net/entry/ogp-generator

    View Slide

  45. ʲখᄉʳCIपΓ
    • ϓϩτλΠϓͷஈ֊Ͱʮpushͷ౓ʹςετ࣮ߦʯతͳCI͸༧Ί४උ.


    • deployλεΫ͸ϓϩμΫτͷϦϦʔεස౓Λݟͯ։ൃɾ౤ೖΛ൑அ.

    ݸਓతʹ͸ຖ೔ϦϦʔε͕ൃੜ͢Δ༧ஹ͕ݟ͑ͨΒ੔͑Δ༻ʹ͍ͯ͠Δ.


    • ͜ͷลͷԘക͸ࢥ૝ɾߟ͑ํɾ޷Έ΋͋ΔͷͰask the speaker͋ͨΓͰ

    ձ࿩͍͔ͨ͠΋, ͦΕͳΓʹτϨʔυΦϑ΋͋Δͱࢥ͏ͷͰ.


    • ͪͳΈʹࠓճͷAIΦΦλχαϯ͸Github ActionsͰςετ->deploy·Ͱ༻ҙͨ͠

    View Slide

  46. AIΦΦλχαϯͷdeployϑϩʔ
    mainϒϥϯνʹpushͨ͠த਎͕Ϗϧυ͞ΕͯCloud Runʹdeploy͞ΕΔ࢓૊Έ


    ޙͷεϥΠυͰܰ͘ղઆ͠·͢

    View Slide

  47. ͜Μͳײ͡ʢงғؾʣ
    name: C
    I

    on: pus
    h

    jobs
    :

    test
    :

    name: tes
    t

    runs-on: ubuntu-lates
    t

    steps
    :

    - uses: actions/checkout@maste
    r

    - name: Instal
    l

    uses: abatilo/[email protected].
    0

    with
    :

    python_version: 3.9.
    7

    poetry_version: 1.1.
    7

    args: instal
    l

    - name: Run pytes
    t

    uses: abatilo/[email protected].
    0

    with
    :

    python_version: 3.9.
    7

    poetry_version: 1.1.
    7

    args: run python -m pytest
    .

    deploy
    :

    name: Deplo
    y

    needs: tes
    t

    if: github.ref == 'refs/heads/main
    '

    runs-on: ubuntu-lates
    t

    steps
    :

    - uses: actions/checkout@maste
    r

    - name: Deploy a Cloud Run servic
    e

    id: deploy-servic
    e

    uses: google-github-actions/deploy-cloudrun@mai
    n

    with
    :

    image: asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/ohtani-hr-predic
    t

    service: ohtani-hr-predic
    t

    region: asia-northeast
    1

    project_id: ${{ secrets.GCP_PROJECT_ID }
    }

    credentials: ${{ secrets.GCP_SA_KEY }}

    View Slide

  48. ݁ͼ

    View Slide

  49. ʲ࠶ܝʳAIϓϩδΣΫτʹඞཁͳελϯε
    • ෆ࣮֬ͳϓϩδΣΫτ͸Agileͳ΍ΓํͰղܾ͍ͯ͘͠


    • σʔλαΠΤϯςΟετͱΤϯδχΞ͸ҧ͏ੜଶܥͷੜ͖෺

    νʔϜϫʔΫΛେ੾ʹʂ


    ͜Ε͕େࣄ΍Ͱʂͬͯ࿩Λ࠷ॳʹ͠·ͨ͠

    View Slide

  50. ʲֆʳAIϓϩδΣΫτ͕ੈʹग़Δ·Ͱ
    গͳ͘ͱ΋اը͔Β࠷ॳʹग़Δ·Ͱ͸͜ΜͳϊϦ͔ͳ?

    View Slide

  51. ͓Θ͔Γ͍͚ͨͩͨͩΖ͏͔?
    σʔλαΠΤϯςΟετͱΤϯδχΞͷʮؿਫҬʯΛ੍͢Δ΋ͷ͕


    ϓϩδΣΫτΛ੍͢Δʢͱࢲ͸৴͍ͯ͡·͢ʣ

    View Slide

  52. खஈͱϓϩηε, ྆ํͰAgilityΛߴΊΔ
    • ࠷ॳ͸ࡶͰ΋͍͍͔Βͬ͞͞ͱಈ͘΋ͷΛ࡞ͬͯݟͤΔ


    • MVP͔ΒຊϓϩμΫτ΁ͷҠߦ…ͷલʹςετͱϦϑΝΫλϦϯά

    ͜͜Ͱ͍͍ײ͡ʹͰ͖Δ͔Ͳ͏͔͕͜ͷઌͷAgilityʹӨڹ͢Δ


    • ϦϦʔε΍ߴෛՙରࡦͳͲ, ܁Γฦ͠΍Δ΋ͷΛCIʹͨ͠Γ࢓૊Έʹ৐͔ͬͬͨΓ

    ͜Ε͸ΤϯδχΞͳࢹ఺Ͱͷ࿹ͷݟͤͲ͜Ζ💪


    • ͜ΕΒΛ͢΂ͯͷϑΣʔζΛҰ؏ͯ͠ಉ͡ݴޠͰ΍ΕΔPython͸,

    ࠷ॳʹϓϩδΣΫτΛ࢝ΊΔͱ͖ͷखஈͱͯ͠ྑ͍ؾ͕͢Δ.

    ʢͨͩ͠, ͦͷޙผݴޠͰ࡞Γ௚͢ͳͲͳͲ͸શવ͋Γʣ

    View Slide

  53. αΫοͱಈ͘Ϟϊ࡞ͬͯมԽʹରԠ͢Δ
    ࢲͨͪ͸ɺιϑτ΢ΣΞ։ൃͷ࣮ફ
    ͋Δ͍͸࣮ફΛखॿ͚Λ͢Δ׆ಈΛ௨ͯ͡ɺ
    ΑΓΑ͍։ൃํ๏Λݟ͚ͭͩͦ͏ͱ͍ͯ͠Δɻ
    ͜ͷ׆ಈΛ௨ͯ͠ɺࢲͨͪ͸ҎԼͷՁ஋ʹࢸͬͨɻ
    ϓϩηε΍πʔϧΑΓ΋ݸਓͱର࿩Λɺ
    แׅతͳυΩϡϝϯτΑΓ΋ಈ͘ιϑτ΢ΣΞΛɺ
    ܖ໿ަবΑΓ΋ސ٬ͱͷڠௐΛɺ
    ܭըʹै͏͜ͱΑΓ΋มԽ΁ͷରԠΛɺ
    Ձ஋ͱ͢Δɻ͢ͳΘͪɺࠨهͷ͜ͱ͕ΒʹՁ஋͕͋Δ͜ͱΛ
    ೝΊͳ͕Β΋ɺࢲͨͪ͸ӈهͷ͜ͱ͕ΒʹΑΓՁ஋Λ͓͘ɻ
    https://agilemanifesto.org/iso/ja/manifesto.html

    View Slide

  54. ΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍
    • ϓϩμΫτΛ։ൃʢӡ༻ʣ͢ΔΤϯδχΞͱ, AIͳ࢓ࣄΛ͢ΔσʔλαΠΤϯςΟετ͸ಘҙෆಘҙ͕ҧ͏

    ಉ͡Pythonͱ͍͏ݴޠΛૢ͍ͬͯͯ΋ҧ͏ੜଶܥͰੜ͖͍ͯΔੜ͖෺Ͱ͋Δʢͱࢥ͓ͬͯ͘΂͖ʣ


    • ྫ͑͹ΤϯδχΞ͸όʔδϣϯ؅ཧɾςετɾCIΛίπίπͱ΍Δʢ΍Δ΂͖ͩʣ͕

    σʔλαΠΤϯςΟετ͸Ͱ͖Δਓ΋͍Ε͹Ͱ͖ͳ͍ਓ΋͍Δ

    ʢͳ͓, ྆ํͰ͖ΔԽ͚෺͸গ਺Ͱ͕͢ଘࡏ͢Δʣ


    • ྫ͑͹σʔλαΠΤϯςΟετ͸਺ֶɾ਺ࣜʹڧ͍ʢڧ͘ͳ͍ͱ͍͚ͳ͍ʣ

    ͕, ΤϯδχΞ͸ผʹͦ͜·ͰٻΊΒΕͳ͍ʢͳ͓྆ํͰ͖ΔԽ͚෺͸গ਺͕ͩҎԼུʣ


    • ͭ·Δͱ͜Ζɺ྆ऀʹٻΊΒΕΔεΩϧηοτɾελϯε͸ڞ௨఺͸͋ΕͲ༏ઌ౓͕શ͘ҟͳΔ

    ಉ͡PythonΛಡΈॻ͖͢Δʹͯ͠΋ࢲʢ͋ͳͨʣ͕େ੾ʹ͢Δॱং͸͋ͳͨʢࢲʣͱશવҧ͏ͱ৺ಘΔ΂͖

    View Slide

  55. ʮ࢓ࣄͰ͸͡ΊΔػցֶश ୈ2൛ʯΛಡΜͰࢥͬͨʮιϑτ΢ΣΞΤϯδχΞͱσʔλαΠΤϯςΟετ, ML Opsʯͷ͜ͱ


    https://shinyorke.hatenablog.com/entry/ml-ops-and-engineering
    ʲ࠶ܝʳΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍

    View Slide

  56. ৭ʑ࿩͠·͕ͨ͠


    ݁ہԿ͕ݴ͍͍͔ͨͱ͍͏ͱ

    View Slide

  57. ʮ͍͍͔Μ͡ʹ͢ΔPythonicͳ΍Γ͔ͨʯ

    is


    ʮαΫοͱಈ͘΋ͷΛ࡞ͬͯ΍ͬͯ͜💪ʯ


    ΨϯΨϯͱσϦόϦʔ͍ͯ͜͠͏ʂ

    View Slide

  58. ँࣙ
    • JX௨৴ࣾͰ৭ʑ΍Βͤͯ΋Βͬͨܦݧ͕ࠓճͷൃදʹ׆͖ͨ


    • ௅ઓͱֶͼͷػձΛ͘ΕͨJX௨৴ࣾʹ͸ϗϯτʹຊ౰ʹ͓ੈ࿩ʹͳΓ·ͨ͠🙇


    • ςοΫϒϩά https://tech.jxpress.net/ Έͯ΍͍ͬͯͩ͘͞📝

    ͋ͱ, εϙϯαʔϒʔε΋ͥͻ༡ͼʹߦͬͯ΋Β͑Δͱ👍


    • ͳ͓ຊ೔16:20͔ΒαʔόʔαΠυΤϯδχΞ @TatchNicolas ͕

    ʮLocust࣮ફฤʯͱ͍͏τʔΫ͢ΔͷͰؾʹͳΔํ͸νΣοΫΛʂ

    View Slide

  59. ήʔϜηοτ⚾
    ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠.


    Shinichi Nakagawa(Twitter/Facebook/etc… @shinyorke)

    View Slide

  60. ʲAppendixʳࢀߟจݙɾϒϩά
    • JX௨৴ࣾΤϯδχΞϒϩά


    • https://tech.jxpress.net/entry/data-app-for-streamlit


    • https://tech.jxpress.net/entry/vaccine-gae


    • https://tech.jxpress.net/entry/ogp-generator


    • Lean Baseball


    • https://shinyorke.hatenablog.com/entry/
    fl
    ask-and-gae-and-github-actions


    • https://shinyorke.hatenablog.com/entry/engineer-and-datascientist


    • https://shinyorke.hatenablog.com/entry/jupyter-to-streamlit


    • Agile Manifest


    • https://agilemanifesto.org/iso/ja/manifesto.html


    • ࢓ࣄͰ͸͡ΊΔػցֶश ୈ2൛


    • https://www.oreilly.co.jp/books/9784873119472/


    View Slide