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

watsonx.ai Dojo #6 継続的なAIアプリ開発と展開

watsonx.ai Dojo #6 継続的なAIアプリ開発と展開

IBMビジネスパートナー・コミュニティである愛徳会のAI未来創造委員会主催の勉強会シリーズです。

最終回の第6回目は、これまで学習してきたことを組み合わせて、大規模言語モデルを利用したAIアプリの継続的な開発と展開の方法を学びます。素早くアプリを開発するために、watsonx.aiでAI推論を行う最低限のコードから出発し、StreamlitやFast APIを利用して、アプリを少しずつ変更しながら機能を強化することを体験します。企業独自のAIアプリだけではなく、AIを組み込んだソリューションの継続的な発展、パートナーエコシステムへの発展などを一緒に考えていきます。

Avatar for Akira Onishi (IBM)

Akira Onishi (IBM)

January 13, 2025
Tweet

More Decks by Akira Onishi (IBM)

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ 1SPQFSUZ 7BMVF ࢯ໊ େ੢ জ Y-JOLFE*O POJBL *5ۀքྺ ೥໨

    ௚ۙͷ৬ྺ Microsoft ೥ *#.೥໨ )BTI5BH ͍͍Ͷ͐੩Ԭੜ׆RVBOUJD ࠲ӈͷ໏ ౿·Εͯ΋ͳ্ཱ͓͕ͪΔಓͷ૲ Α͘࢖͏ٕ ೴಺ม׵Ͱࣗ෼ΛϙδςΟϒʹ IUUQTXXXGBDFCPPLDPNBLJSBPOJTIJ 'BDFCPPLʮ͓ʹ͋͘ʯͰݕࡧ
  2. ४උͷͨΊͷࢀߟࢿྉ IUUQTTQFBLFSEFDLDPNPOJBLJCNXBUTPOYBJEPKPQSFSFR ϋϯζΦϯ؀ڥͷ४උ ؀ڥ ର৅ऀ *#.5FDIOPMPHZ;POF *#.άϧʔϓࣾһ *#.1BSUOFS1MVTʹొ࿥ࡁΈͷϏδωεɾύʔτφʔ༷ *#.XBUTPOYBJ೔ແྉධՁ൛ ҰൠͷࢀՃऀͰɺ*#.$MPVEͷΞΧ΢ϯτΛ͓࣋ͪͰͳ͍৔߹

    ධՁ൛΁ͷΞΫηεʹ͸ΫϨδοτɾΧʔυ͸ෆཁ ೔ܦաޙ͸ɺΫϨδοτɾΧʔυΛొ࿥͢Δͱैྔ՝ۚΞΧ΢ϯτͱ ͯ͠ɺશͯͷ*#.$MPVEͷαʔϏε͕͝ར༻͍͚ͨͩ·͢ *#.$MPVE ҰൠͷࢀՃऀͰɺ*#.$MPVEͷΞΧ΢ϯτΛ͓࣋ͪͷ৔߹
  3. • 3&45ʹΑΓXBUTPOY"1*Λར༻͢Δ • XBUTPOYαʔϏεΛ࢖͍΍ͨ͘͢͠ΫϥΠΞϯτɾϥΠϒϥϦʔΛ࢖͏ B XBUTPOY"1*Λར༻ͨ͠ΞϓϦΛ࡞Γɺల։͢Δ "*ΞϓϦ XBUTPOYαʔϏε 63- "*ΞϓϦ

    3&45 3&45 IUUQTHJUIVCDPN*#.KBQBOUFDIOPMPHZUSFFNBJOXBUTPOYBJEPKP1SPNQU-BC XBUTPOY1ZUIPO ϥΠϒϥϦ "1* IUUQTHJUIVCDPN*#.KBQBOUFDIOPMPHZCMPCNBJOXBUTPOYBJEPKPSBHMDRBQZ "1*Ωʔ͔Βੜ੒ͨ͠ΞΫηετʔΫϯ 1SPKFDU*% Ϟσϧͷࢦఆ ύϥϝʔλͷࢦఆ ϓϩϯϓτจࣈྻ
  4. XBUTPOYBJ3VOUJNFʹσϓϩΠͨ͠αʔϏεʹΞΫηε͢Δ • 3&45αʔϏεʹ௚઀ΞΫηε͢Δ • XBUTPOYαʔϏεΛ࢖͍΍ͨ͘͢͠ΫϥΠΞϯτɾϥΠϒϥϦʔΛ࢖͏ C XBUTPOYBJ3VOUJNFʹ8FCαʔϏεΛల։͢Δ "*ΞϓϦ σϓϩΠͨ͠αʔϏε 3&45

    IUUQTHJUIVCDPN*#.KBQBOUFDIOPMPHZUSFFNBJOXBUTPOYBJEPKPJOWPLFXFCBQJ "*ΞϓϦ XBUTPOY1ZUIPO ϥΠϒϥϦ 3&45 "1*Ωʔ͔Βੜ੒ͨ͠ΞΫηετʔΫϯ 1SPKFDU*% 4QBDF*% %FQMPZNFOU*% αʔϏε΁ͷೖྗʢจࣈྻͳͲʣ
  5. from ibm_watsonx_ai import APIClient from ibm_watsonx_ai import Credentials from ibm_watsonx_ai.foundation_models

    import ModelInference credentials = Credentials( url = "https://jp-tok.ml.cloud.ibm.com", api_key = ”<APIΩʔ>" ) client = APIClient(credentials) model = ModelInference( model_id="ibm/granite-3-8b-instruct", api_client=client, project_id=”<ϓϩδΣΫτID>", params = { "max_new_tokens": 500 } ) XBUTPOYBJݴޠϞσϧʹΑΔਪ࿦ॲཧͷ࠷খίʔυ prompt = ”C#Λ࢖ͬͯONNXϞσϧΛݺͼग़͢ίʔυΛ࡞੒͍ͯͩ͘͠͞ɻ" print(model.generate_text(prompt))
  6. /HJOYΛϦόʔεɾϓϩΩγͱͯ͠ɺ"*ΞϓϦʹ઀ଓ ϒϥ΢β 4USFBNMJUΞϓϦͷల։ྫ ϦόʔεɾϓϩΩγ OHJOY NZEPNBJOBQQ "*ΞϓϦ BQQ QSPYZ@QBTT TUSFBNMJUSVOBQQQZTFSWFSBEESFTTTFSWFSQPSUTFSWFSCBTF6SM1BUIBQQTFSWFSFOBCMF$034GBMTF

    # /etc/nginx/conf.d/default.conf location /app1/ { proxy_pass http://127.0.0.1:8501/app1/; proxy_redirect http:// https://; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } /HJOYͱ"*ΞϓϦ͕ಉ͡ίϯϐϡʔλʔ্ʹ͋Δ৔߹ IUUQTEPDTTUSFBNMJUJPLOPXMFEHFCBTFEFQMPZSFNPUFTUBSU
  7. 'BTU"1*ͷΠϯετʔϧQJQJOTUBMMGBTUBQJ 'BTU"1*Λ࢖ͬͨ"1*αʔόʔͷ࡞੒ IUUQTGBTUBQJUJBOHPMPDPNKB ։ൃ؀ڥͰͷ࣮ߦྫ VWJDPSOTJNQMFBQJBQQSFMPBE TJNQMFBQJQZ಺ͷBQQΛ࣮ߦ ίʔυ͸࣍ϖʔδ "1*ݺͼग़͠ྫ IUUQQSPNQU R$&"0//9&

    "&&"#&&#$& #&#"&&#&#$& &&#%$&&& "&'&"&&& 
  8. from ibm_watsonx_ai import APIClient from ibm_watsonx_ai import Credentials from ibm_watsonx_ai.foundation_models

    import ModelInference import time import logging API_KEY="<APIΩʔ>" PROJECT_ID="<Project ID>" credentials = Credentials( url = "https://jp-tok.ml.cloud.ibm.com", api_key = API_KEY ) logger = logging.getLogger('uvicorn') def connect_watsonx(): start = time.perf_counter() cli = APIClient(credentials) end = time.perf_counter() logger.info("watsonx΁ͷ௨৴ཱ֬:"+str(end-start)) return cli TJNQMFBQJQZ def load_model(): start = time.perf_counter() m = ModelInference( model_id="ibm/granite-3-8b-instruct", api_client=connect_watsonx(), project_id=PROJECT_ID, params = { "max_new_tokens": 600 } ) end = time.perf_counter() logger.info("LLMͷઃఆ׬ྃ:"+str(end-start)) return m from fastapi import FastAPI app = FastAPI() model = load_model() @app.get("/prompt/") def read_item(q: str = None): start = time.perf_counter() generated_string = model.generate_text(q) end = time.perf_counter() logger.info("ਪ࿦࣌ؒ:"+str(end-start)) return {"generated_text": generated_string}
  9. XBUTPOYBJͷΑ͏ͳ"*ϓϥοτϑΥʔϜ͕ඞཁͳཧ༝ ΞϓϦʢ8FCϢʔβʔΠϯλʔϑΣΠεʣ ΞϓϦɾϓϥοτϑΥʔϜ "*ΞϓϦ Ϗδωεɾ ϩδοΫ "*Ϟσϧ ϥΠϒϥϦ"1* "*ΞϓϦɾϓϥοτϑΥʔϜ ໰͍߹Θͤ

    ੜ੒݁Ռ ཤྺ σʔλ ࢖༻ྔ σʔλ "*ͷ࣮ݧ͸ΦʔϓϯιʔεͰ΋Մೳ ҰํɺاۀϨϕϧ΁ͷల։͸՝୊͕ଟ͍ 4BB4൛ͷXBUTPOYBJΛ࢖͑͹ɺ ΞϓϦ։ൃɺల։ɺӡ༻ʹूதͰ͖Δ
  10. ϫʔΫγϣοϓɺηογϣϯɺ͓Αͼࢿྉ͸ɺ*#.·ͨ͸ηογϣϯൃදऀʹΑͬͯ४උ͞ΕɺͦΕͧΕಠࣗͷݟղΛ൓өͨ͠΋ͷͰ͢ɻͦΕΒ͸৘ใ ఏڙͷ໨తͷΈͰఏڙ͞Ε͓ͯΓɺ͍͔ͳΔࢀՃऀʹରͯ͠΋๏཯త·ͨ͸ͦͷଞͷࢦಋ΍ॿݴΛҙਤͨ͠΋ͷͰ͸ͳ͘ɺ·ͨ*#.੡඼΍αʔϏε͕͓ ٬༷ʹద༻͋Δಛఆͷ๏ྩʹద߹͢Δ͜ͱΛอূ͢Δ΋ͷͰ΋͋Γ·ͤΜɻຊߨԋࢿྉʹؚ·Ε͍ͯΔ৘ใʹ͍ͭͯ͸ɺ׬શੑͱਖ਼֬ੑΛظ͢ΔΑ͏౒ Ί͓ͯΓ·͕͢ɺʮݱঢ়ͷ··ʯఏڙ͞Εɺ໌ࣔ·ͨ͸໧ࣔʹ͔͔ΘΒͣɺ঎ۀੑɺಛఆͷ໨త΁ͷద߹ੑɺඇ৵֐ੑΛؚΊɺ͍͔ͳΔอূ΋൐Θͳ͍ ΋ͷͱ͠·͢ɻຊߨԋࢿྉ·ͨ͸ͦͷଞͷࢿྉͷ࢖༻ʹΑͬͯɺ͋Δ͍͸ͦͷଞͷؔ࿈ʹΑͬͯɺ͍͔ͳΔଛ֐͕ੜͨ͡৔߹΋ɺ*#.͸੹೚ΛෛΘͳ͍ ΋ͷͱ͠·͢ɻ ຊߨԋࢿྉͰݴٴ͞ΕΔ*#.੡඼ɺϓϩάϥϜɺ·ͨ͸αʔϏε͸ɺ*#.͕ϏδωεΛߦ͍ͬͯΔ͢΂ͯͷࠃɾ஍ҬͰ͝ఏڙՄೳͳΘ͚ Ͱ͸͋Γ·ͤΜɻຊߨԋࢿྉͰݴٴ͞ΕΔকདྷͷల๬ʢ੡඼ϦϦʔε೔෇΍੡඼ػೳΛؚΉʣ͸ɺࢢ৔ػձ·ͨ͸ͦͷଞͷཁҼʹج͍ͮͯ*#.ಠࣗͷܾ ఆݖΛ΋͍ͬͯͭͰ΋มߋͰ͖Δ΋ͷͱ͠ɺকདྷͷ੡඼·ͨ͸ػೳ͕࢖༻ՄೳʹͳΔ͜ͱɺ΋͘͠͸ಛఆͷ݁ՌΛ֬໿͢Δ͜ͱΛҙਤ͢Δ΋ͷͰ͸͋Γ ·ͤΜɻຊߨԋࢿྉ͸ɺݴٴ͞ΕΔ

    *#.੡඼·ͨ͸αʔϏεʹద༻͋Δܖ໿৚݅Λมߋ͢Δ΋ͷͰ΋ɺ௥Ճͷද໌·ͨ͸อূΛҙਤ͢Δ΋ͷͰ΋͋Γ· ͤΜɻ ຊߨԋࢿྉʹؚ·Ε͍ͯΔ಺༰͸ɺࢀՃऀͷ׆ಈʹΑͬͯಛఆͷ݁Ռ͕ੜ͡Δͱड़΂Δɺ·ͨ͸҉ࣔ͢Δ͜ͱΛҙਤͨ͠΋ͷͰ΋ɺ·ͨͦͷΑ͏ͳ݁Ռ ΛੜΉ΋ͷͰ΋͋Γ·ͤΜɻ ύϑΥʔϚϯε͸ɺ؅ཧ͞Εͨ؀ڥʹ͓͍ͯඪ४తͳ*#.ϕϯνϚʔΫΛ࢖༻ͨ͠ଌఆͱ༧ଌʹج͍͍ͮͯ·͢ɻϢʔβʔ ͕ܦݧ͢Δ࣮ࡍͷεϧʔϓοτ΍ύϑΥʔϚϯε͸ɺϢʔβʔͷδϣϒɾετϦʔϜʹ͓͚ΔϚϧνϓϩάϥϛϯάͷྔɺೖग़ྗߏ੒ɺετϨʔδߏ੒ɺ ͓Αͼॲཧ͞ΕΔϫʔΫϩʔυͳͲͷߟྀࣄ߲ΛؚΉɺ਺ଟ͘ͷཁҼʹԠͯ͡มԽ͠·͢ɻ͕ͨͬͯ͠ɺݸʑͷϢʔβʔ͕͜͜Ͱड़΂ΒΕ͍ͯΔ΋ͷͱ ಉ༷ͷ݁ՌΛಘΒΕΔͱ֬໿͢Δ΋ͷͰ͸͋Γ·ͤΜɻهड़͞Ε͍ͯΔ͢΂ͯͷ͓٬༷ࣄྫ͸ɺͦΕΒͷ͓٬༷͕ͲͷΑ͏ʹ*#.੡඼Λ࢖༻͔ͨ͠ɺ· ͨͦΕΒͷ͓٬༷͕ୡ੒ͨ݁͠Ռͷ࣮ྫͱͯࣔ͠͞Εͨ΋ͷͰ͢ɻ࣮ࡍͷ؀ڥίετ͓ΑͼύϑΥʔϚϯεಛੑ͸ɺ͓٬༷͝ͱʹҟͳΔ৔߹͕͋Γ·͢ɻ • *#.ɺ*#.ϩΰɺJCNDPNɺ%C *#.XBUTPOY *#.$MPVE͸ɺ ੈքͷଟ͘ͷࠃͰొ࿥͞Εͨ*OUFSOBUJPOBM#VTJOFTT.BDIJOFT$PSQPSBUJPOͷ঎ඪͰ͢ɻଞͷ੡඼ ໊͓ΑͼαʔϏε໊౳͸ɺͦΕͧΕ*#.·ͨ͸֤ࣾͷ঎ඪͰ͋Δ৔߹͕͋Γ·͢ɻݱ࣌఺Ͱͷ *#.ͷ঎ඪϦετʹ͍ͭͯ͸ɺXXXJCNDPNMFHBMDPQZUSBEFTIUNM Λ͝ཡ͍ͩ͘͞ɻ • %PDMJOH͸"QBDIFϥΠηϯεͰެ։͞Ε͍ͯΔΦʔϓϯιʔεͷϥΠϒϥϦʔͰ͢ɻ