- TOP
- ã¿ã°äžèЧ
- Sass
Sass
ã€ãã³ã
該åœããã³ã³ãã³ããèŠã€ãããŸããã§ãã
ãã¬ãžã³
該åœããã³ã³ãã³ããèŠã€ãããŸããã§ãã
æè¡ããã°
MathJax={tex:{inlineMath:[['$','$']],displayMath:[['$$','$$']],processEscapes:true}}; ããã«ã¡ã¯ãInsight Edgeã§ããŒã¿ãµã€ãšã³ãã£ã¹ããããŠããæ°èŠã§ãã cuTile Pythonãšã¯ èæ¯ ç¹åŸŽ åŸæ¥ã®CUDAïŒSIMTïŒãšã®éã ææ³ TileGymã§è¡åç©ãã³ãããŒã¯ å粟床è¡åç©ãšãã¥ã¬ãŒã·ã§ã³ Ozaki Schemeã«ã€ã㊠åè§£(Split) è¡åç©ã®èšç® çŽ æŽãªå®è£
ãšååçµæ æé©å Fast ModeïŒGEMMã®åæžïŒ Fused Split KernelïŒåå²ã®èåïŒ æé©ååŸã®çµæ dã«ãã粟床/é床ãã¬ãŒããªã ãŸãšã åèæç® ä»åã¯NVIDIAãçºè¡šããã°ããã®ãcuTile Pythonãã詊ããŠã¿ãŸãããæ®æ®µã¯ãGPUã«ãŒãã«ãæ¥åã§æžãããšã¯ãããŸããããcuTileã¯Pythonã§æžãããŠããŠãææ³ãã·ã³ãã«ãªãããªã®ã§ãGPUããã°ã©ãã³ã°ã®ååŒ·ã®æå³ãå«ããŠèšäºã«ããŸããã cuTile Pythonãšã¯ cuTile Pythonã¯ãNVIDIA GPUåãã®æ°ãã䞊åããã°ã©ãã³ã°ã¢ãã«ãcuTileããPythonãã䜿ãããã®DSLïŒãã¡ã€ã³åºæèšèªïŒã§ãã èæ¯ GPUäžã§é«éã«åäœããåŠçãèªåã§èšè¿°ãããå Žé¢ã¯å¢ããŠããŸãããCUDA C++ã®ç¿åŸã³ã¹ãã¯äŸç¶ãšããŠé«ãã®ã宿
ã§ãã PyTorchãcuBLASãšãã£ãé«ã¬ãã«APIã§æ¥åžžçãªéçºã¯ååã«ããŒã§ãããã®ã®ãLLMæšè«ã®æé©åãªã©äœã¬ã€ã€ãžã®ä»å
¥ãæ±ããããå±é¢ãå¢ããŠããŸãããNVIDIA Ampereäžä»£ä»¥éã®GPUã§ã¯Tensor CoreãTMAïŒTensor Memory AcceleratorïŒãšãã£ãããŒããŠã§ã¢æ©èœã远å ãããŠãããããããååã«æŽ»çšããã«ã¯ããèžã¿èŸŒãã ããã°ã©ãã³ã°ãå¿
èŠã«ãªããŸãã ããããããŒããŠã§ã¢ãæèããã³ãŒããæžãé£æåºŠã¯äžããç¶ããŠããŸããã¡ã¢ãªéå±€ã²ãšã€åã£ãŠããå
±æã¡ã¢ãªãã¬ãžã¹ã¿ãBlackwelläžä»£ã§è¿œå ãããTensor Memoryãªã©ãçšéã«å¿ããŠäœ¿ãåããå¿
èŠããããããããã®ç¹æ§ã«åãããããŒã¿é
眮ã転éã®å¶åŸ¡ãæ±ããããŸãã ããã«ãç¹å®ã®ã¢ãŒããã¯ãã£ã«æé©åããã³ãŒãã¯æ°ããäžä»£ã®GPUãç»å Žããéç«¯ã«æžãçŽããå¿
èŠã«ãªãããšãå€ããä¿å®ã³ã¹ããç¡èŠã§ããŸããã ããããèæ¯ãããããŒããŠã§ã¢ã®è©³çŽ°ãæœè±¡åãã€ã€é«ãæ§èœãåŒãåºãDSLãžã®éèŠãé«ãŸã£ãŠããŸããOpenAIã® gpt-oss ãªããžããªã§ãTritonãšããåæ§ã®DSLãæ¡çšãããŠããããã®æã®ã¢ãããŒãã¯æ¥çã§ãåºã泚ç®ãããŠããŸãã ç¹åŸŽ GPUããã°ã©ãã³ã°ã«ã¯ãcuBLASãPyTorchã®ãããªé«ã¬ãã«ã©ã€ãã©ãªããCUDA C++ãPTXãšãã£ãäœã¬ãã«ãªã¹ã¬ããå¶åŸ¡ãããšããäºæ¥µåããããŸãããcuTileã¯ãã®äžéã«äœçœ®ãããTileã¬ãã«ãã®ããã°ã©ãã³ã°ã¢ãã«ã§ãã æœè±¡ã¬ãã«ã«ã€ããŠïŒåç»[1]ããïŒ ä»¥äžãåç»[1]ã§ç޹ä»ãããŠããç¹åŸŽã«ãªããŸãã CUDAãã©ãããã©ãŒã ã«ãã€ãã£ãçµ±å : OpenAI Tritonãªã©ãµãŒãããŒãã£è£œDSLãšã¯ç°ãªããcuTileïŒTile IRïŒã¯CUDAãã©ã€ãã«çµã¿èŸŒãŸããŠããŸããæ¢åã®ãããã¡ã€ã©ããããã¬ããã®ãŸãŸäœ¿ããŸãã Tile IRãžã®ã³ã³ãã€ã« : Pythonã§æžããã«ãŒãã«ã¯ãTile IRããšããä»®æ³ISAã«å€æããããã©ã€ããå®è¡æã«ã¿ãŒã²ããGPUã«åãããæé©ãªãã·ã³ã³ãŒãïŒSASSïŒãçæããŸãã æè¡ã¹ã¿ãã¯ã®éå±€æ§é ãTileIRã¯PTXã眮ãæããã®ã§ã¯ãªãå
±åããïŒåç»[1]ããïŒ åŸæ¥ã®CUDAïŒSIMTïŒãšã®éã åŸæ¥ã®CUDAïŒSIMT: Single Instruction, Multiple ThreadsïŒãšcuTileã§ã¯ãããã°ã©ããäœãæžããŠäœãã·ã¹ãã ã«ä»»ãããã倧ããç°ãªããŸãã ç¹åŸŽ åŸæ¥ã®CUDA (SIMT) cuTile (Tile-based) å®è¡åäœ ã¹ã¬ããåäœã§ããŒã¿åŠçãèšè¿°ãWarpãBlockã®æ§æãæèããå¿
èŠããã ããŒã¿ã®å¡ïŒã¿ã€ã«ïŒãšåäžã®å®è¡åäœïŒãããã¯ïŒã§æèãã¹ã¬ãããžã®åè§£ã¯ã·ã¹ãã ãè¡ã ããŒã¿åŠç åã
ã®ã¹ã¬ãããžã®ããŒã¿åé
ïŒã¹ãã©ã€ãã£ã³ã°ãªã©ïŒãæåã§èšç®ã»ç®¡ç ã¿ã€ã«ïŒé
åå
šäœã®äžéšïŒãäžã€ã®åäœãšããŠããŒãã»æŒç®ã»ã¹ã㢠ã¡ã¢ãªç®¡ç å
±æã¡ã¢ãªã®ç¢ºä¿ãåæïŒããªã¢ïŒããã³ã¯ã³ã³ããªã¯ãåé¿ãªã©ããŠãŒã¶ãŒã管ç ã·ã¹ãã ã管çãå
±æã¡ã¢ãªã®å©çšãåæã¯èªååããããŠãŒã¶ãŒããã¯é èœ ããŒããŠã§ã¢æŽ»çš Tensor Coreãªã©ã䜿ãã«ã¯è€éãªPTXåœä»€ãç¹å®ã®ã¬ã€ã¢ãŠããæèããå¿
èŠããã ct.load ãæŒç®åãæžãã ãã§TMAãTensor Coreãèªåçã«æŽ»çš ææ³ cuTile Pythonã¯ãPythonã®ãã³ã¬ãŒã¿ãšå°çšã®åã·ã¹ãã ã䜿ã£ãŠèšè¿°ããŸãã詳ããã¯å
¬åŒããã¥ã¡ã³ã[2]ãåç
§ããŠãã ããã äž»ãªç¹åŸŽ: @ct.kernel ãã³ã¬ãŒã¿ : Python颿°ãGPUã«ãŒãã«ãšããŠããŒã¯ã颿°å
ã§ã¯cuTile Pythonã®ææ³ã«åŸãã ã€ãã¥ãŒã¿ãã«ãªã¿ã€ã« : ã«ãŒãã«å
ã§ã¯ãã¿ã€ã«ãæäœå¯Ÿè±¡ãšãªããã¿ã€ã«ã¯ãå€ããšããŠæ±ããã倿Žäžå¯ãæŒç®ãããšæ°ããã¿ã€ã«ãçæãããŸã Array (Global Memory): åŒæ°ããååŸããã¥ãŒã¿ãã«ã ct.load / ct.store ã§ã¢ã¯ã»ã¹ Tile (Local/Register): ã€ãã¥ãŒã¿ãã«ã§æŒç®å¯Ÿè±¡ 以äžããã¯ãã«å ç®ã®ã³ãŒãäŸã§ãã import cuda.tile as ct # ã¿ã€ã«ãµã€ãºã¯ã³ã³ãã€ã«æå®æ° TILE_SIZE = 16 @ ct.kernel def vector_add_kernel (a, b, result): # 1. çŸåšã®ãããã¯IDãååŸ (ã¹ã¬ããIDã§ã¯ãªãïŒ) block_id = ct.bid( 0 ) # 2. ã°ããŒãã«ã¡ã¢ãª(Array)ããã¿ã€ã«ãšããŠããŒã¿ãããŒã # ã·ã¹ãã ãèªåçã«æé©ãªã¡ã¢ãªè»¢é(TMAç)ãè¡ã a_tile = ct.load(a, index=(block_id,), shape=(TILE_SIZE,)) b_tile = ct.load(b, index=(block_id,), shape=(TILE_SIZE,)) # 3. ã¿ã€ã«åå£«ã®æŒç® (èŠçŽ ããšã®å ç®ãäžæ¬ã§è¡ããã) result_tile = a_tile + b_tile # 4. çµæãã°ããŒãã«ã¡ã¢ãªã«ã¹ã㢠ct.store(result, index=(block_id,), tile=result_tile) # ãã¹ãåŽããã®å®è¡ # ct.launch(stream, grid_dim, kernel_func, args) ãããã¯ããšã«åäžã®ã«ãŒãã«ãå®è¡ãããåãããã¯ã¯IDã§æå®ãããããŒã¿ãæ
åœç¯å²ãšããŠãåŠçãè¡ããŸããã¿ã€ã«æŒç®ã¯ãæèŠãšããŠã¯numpyã®åŠçã«äŒŒãŠããŸãã TileGymã§è¡åç©ãã³ãããŒã¯ å®éã«åãããŸããcuTileã¯CUDA Toolkit13.1以éãå¿
èŠã§ãããã¯Blackwelläžä»£ä»¥éã®æ¯èŒçææ°ã®GPUã§ããåããªãããã§ããç§ã¯æå
ã«ææ°ã®GPUããªãã®ã§ãã¯ã©ãŠããµãŒãã¹ãå©çšããããšæããŸããä»åã¯ã Modal ãšåŒã°ããGPUç¹åã®ã¯ã©ãŠããµãŒãã¹ãå©çšããŸããã Modalã¯é¢æ°ããŒã¹ã§GPUã€ã³ã¹ã¿ã³ã¹ãç«ã¡äžãããããµãŒãã¹ã«ãªããŸãã䜿ãåæãããã䟿å©ã§ããå®è¡æéã«å¿ããåŸé課éå¶ã§ãä»åã®æ€èšŒã®ãããªå°ãGPUã詊ããŠã¿ããå Žåã«é©ããŠããŸãã ä»åã¯ãå
¬åŒã®ãµã³ãã«ã¬ããžããªTileGym[3]ãããŒã¹ã«ãè¡åç©ã®ã³ãŒãã®å®è¡ãããŠã¿ãŸããModalã§èµ°ãããå®è¡ã³ãŒãã以äžã«ç€ºããŸããimageã§Dockerã€ã¡ãŒãžãäœæããTileGymã®ã¬ããžããªãã¯ããŒã³ãã©ã€ãã©ãªã€ã³ã¹ããŒã«ãè¡ããŸããModalã®è©³çŽ°ã¯ ããã¥ã¡ã³ã ãåç
§ããŠãã ãããä»å察象ã®GPUã¯B200ã§ãã # run-tilegym.py import modal image = ( modal.Image.from_registry( "nvidia/cuda:13.1.0-devel-ubuntu24.04" , add_python= "3.13" ) # CUDA 13.1éçºç°å¢ã€ã¡ãŒãž .apt_install( "git" ) .run_commands( "pip install --pre torch --index-url https://download.pytorch.org/whl/cu130" ) # PyTorchã€ã³ã¹ããŒã«ãæ¯èŒã®ãã .run_commands( "git clone https://github.com/NVIDIA/TileGym.git && cd TileGym && pip install -e ." ) # cuTile, TileGymã€ã³ã¹ããŒã« .entrypoint([]) ) app = modal.App( "tilegym-test" ) @ app.function (gpu= "B200" , image=image, timeout= 600 ) def run_mma_bench (): import os os.chdir( "/TileGym" ) os.system( "python tests/benchmark/bench_matrix_multiplication.py" ) @ app.local_entrypoint () def main (): run_mma_bench.remote() äžã®ã³ãŒããrun-tilegym.pyãšããŠä¿åãã modal run run-tilegym.py ã§å®è¡ããŸããåé¡ãªããã°çµæã¯ã以äžã®ããã«åºåãããã¯ãã§ãã matmul-performance-float16-TFLOPS: M N K CuTile PyTorch 0 1024.0 1024.0 1024.0 271.056760 473.522850 1 2048.0 2048.0 2048.0 1129.688506 1199.365877 2 4096.0 4096.0 4096.0 1235.696555 1401.341171 3 8192.0 8192.0 8192.0 1483.030888 1253.946946 4 16384.0 16384.0 16384.0 1356.600018 1536.098446 5 32768.0 32768.0 32768.0 1254.836929 1306.057063 matmul-performance-float8_e5m2-TFLOPS: M N K CuTile 0 1024.0 1024.0 1024.0 277.309352 1 2048.0 2048.0 2048.0 1154.454102 2 4096.0 4096.0 4096.0 2769.415226 3 8192.0 8192.0 8192.0 2981.168986 4 16384.0 16384.0 16384.0 2935.864636 5 32768.0 32768.0 32768.0 2658.604232 CuTileãšPyTorchã®è¡åç©ã®ãã³ãããŒã¯ãåºãŠããŸããfloat16ãšfloat8_e5m2ã®äž¡æ¹ã§è¡åç©ãå®è¡ããŠããŸãããPyTorchã§ã¯ãåŸè
ã®è¡åç©ãæªå¯Ÿå¿ã®ããã§ããPyTorchã¯è£åŽã§cuBLASãåŒã³åºããŠããã®ã§å®è³ªcuBLASãšã®æ¯èŒã§ããfloat16ã§ã¯ãCuTileã¯PyTorchã«è¿ãæ§èœãäžéšã®ãµã€ãºã§ã¯ãPyTorchãäžåãæ§èœãåºãŠããŸããfloat8_e5m2ã§ã¯ãè¡åãµã€ãºã4096以äžã§float16ã®çŽ2åã®æ§èœãåºãŠããŸãã 以äžã TileGym/src/tilegym/ops/cutile/matmul.py ã®è¡åç©ã®ã«ãŒãã«ã³ãŒãã®æç²ã§ãã @ ct.kernel (num_ctas=ct.ByTarget(sm_100= 2 )) def matmul_kernel (A, B, C, TILE_SIZE_M: ConstInt, TILE_SIZE_N: ConstInt, TILE_SIZE_K: ConstInt): # æ
åœã¿ã€ã«ã®ã€ã³ããã¯ã¹èšç®ïŒL2ãã£ãã·ã¥å±ææ§ã®ããswizzleïŒ bidx, bidy = swizzle_2d(A.shape[ 0 ], B.shape[ 1 ], TILE_SIZE_M, TILE_SIZE_N, GROUP_SIZE_M= 8 ) num_tiles_k = ct.num_tiles(A, axis= 1 , shape=(TILE_SIZE_M, TILE_SIZE_K)) # FP32ã¢ãã¥ã ã¬ãŒã¿ã®åæåïŒFP16å
¥åã§ãç²ŸåºŠç¶æã®ããFP32ã§çޝç©ïŒ accumulator = ct.full((TILE_SIZE_M, TILE_SIZE_N), 0 , dtype=ct.float32) # FP32âTF32倿ïŒTensor Coreãå©çšããããïŒ dtype = ct.tfloat32 if A.dtype == ct.float32 else A.dtype # Kæ¹åã«ã¿ã€ã«åäœã§ã«ãŒã for k in range (num_tiles_k): a = ct.load(A, index=(bidx, k), shape=(TILE_SIZE_M, TILE_SIZE_K), padding_mode=ct.PaddingMode.ZERO).astype(dtype) b = ct.load(B, index=(k, bidy), shape=(TILE_SIZE_K, TILE_SIZE_N), padding_mode=ct.PaddingMode.ZERO).astype(dtype) accumulator = ct.mma(a, b, accumulator) # è¡åç©èšç®ã»çŽ¯ç© # åºååã«å€æããŠçµæãæžãåºã ct.store(C, index=(bidx, bidy), tile=ct.astype(accumulator, C.dtype)) A:MxK @ B:KxN -> C:MxN ã®è¡åç©ã§ãMæ¹åãNæ¹ååäœã§ãããã«åãåãCã®éšåã¿ã€ã«ããšã«äžŠè¡ããŠå®è¡ãããŸããKæ¹åã«ãéšååå²ããŠãé æ¬¡èªã¿èŸŒã¿(load), è¡åç©èšç®(mma), çµæã®ä¿å(store)ãè¡ã£ãŠããŸããcuTileåŽã§ã¡ã¢ãªã®çš®é¡ãMMAåœä»€ã®éžæã¯æžãå¿
èŠããªããã³ã³ãã€ã«æã«èªåçã«æé©åãããŸãã ãã®ããã«ç°¡æœã«æžããŠãããŽãªãŽãªã«ãã¥ãŒãã³ã°ããŠããcuBLASã«å¹æµããæ§èœãåºããŠãããšããã®ãcuTileã®å£²ããªããã§ãã ãã³ãããŒã¯ãåãããã ãã§ã¯é¢çœããªãã®ã§ãåã®ç²ŸåºŠãå°ãäžããŠåæ§ã®èšç®ãããŠã¿ãŸããF32æŒç®ã®å Žåãäžèšã³ãŒãã§ã¯è¡åãTF32ã«å€æããŠããèšç®ããŠããŸãããããšåããããããPyTorchåŽã以äžã®ããã«TF32ãæå¹åããŸãã # TileGym/tests/benchmark/bench_matrix_multiplication.py # Enable TF32 for PyTorch to match Tensor Core behavior torch.backends.cuda.matmul.allow_tf32 = True torch.backends.cudnn.allow_tf32 = True ãŸããFP64æŒç®ã«ãããã环ç©ã®åãFP32ã§ã¯ç²ŸåºŠãè¶³ããªããããcutileã³ãŒãåŽã§çޝç©ã®åãFP64ã«å€æŽããåŠçã远å ããŠããŸãã # Initialize an accumulator for the current output tile (TILE_SIZE_M x TILE_SIZE_N). # Use float64 for float64 inputs, otherwise float32 for higher precision accumulation. acc_dtype = ct.float64 if A.dtype == ct.float64 else ct.float32 accumulator = ct.full((TILE_SIZE_M, TILE_SIZE_N), 0 , dtype=acc_dtype) 以äžãä¿®æ£åŸã®ãã³ãããŒã¯çµæã§ãã matmul-performance-float32-TFLOPS: M N K CuTile PyTorch 0 1024.0 1024.0 1024.0 208.295471 294.114105 1 2048.0 2048.0 2048.0 665.976324 648.103430 2 4096.0 4096.0 4096.0 698.961883 747.326296 3 8192.0 8192.0 8192.0 783.858756 761.237840 4 16384.0 16384.0 16384.0 856.688401 742.126004 matmul-performance-float64-TFLOPS: M N K CuTile PyTorch 0 1024.0 1024.0 1024.0 0.855789 26.687611 1 2048.0 2048.0 2048.0 1.063844 33.830530 2 4096.0 4096.0 4096.0 1.124713 35.400544 3 8192.0 8192.0 8192.0 1.124824 35.438650 FP32ã§ã¯ãPyTorchã«è¿ãæ§èœãåºãŠããŸããäžæ¹ãFP64ã§ã¯ãcuTileåŽã§ã®æé©åããŸã äžååãªããã§ãPyTorchã«å€§ããå£ãçµæãšãªã£ãŠããŸããTILE_SIZEãããå°ããèšå®ããããšã§ã1.6 TFLOPSçšåºŠã«ã¯æ¹åããŸãããããŸã 倧ããå£ã£ãŠããŸãã åå ãšããŠã¯ãcuTileã® ct.mma ãFP64æŒç®ã«å¯ŸããŠå¹ççãªåœä»€ãžãããã³ã°ã§ããŠããªãå¯èœæ§ãé«ãã§ããcuBLASïŒPyTorchïŒã¯FP64 Tensor Coreãå«ãããŒããŠã§ã¢ãªãœãŒã¹ãæå€§éã«æŽ»çšããæçããå®è£
ãæã£ãŠããããã®å·®ãæ§èœå·®ã«çŽçµããŠããŸãã ããã§ãFP64æŒç®ã®æ§èœãåäžãããããã«ãOzaki SchemeãšåŒã°ããå粟床è¡åç©ãšãã¥ã¬ãŒã·ã§ã³ææ³ã詊ããŠã¿ãŸãã å粟床è¡åç©ãšãã¥ã¬ãŒã·ã§ã³ Ozaki Schemeã«ã€ã㊠Ozaki Schemeã¯ãFP64ã®è¡åç©ãFP64æŒç®ãªãã§é«ç²ŸåºŠã«ãšãã¥ã¬ãŒãããææ³ã§ã[4][5]ã詳ããã¯å
ã®è«æãèªãã§ã»ããã®ã§ãããæŠèŠã説æããŸããåºæ¬çãªã¢ã€ãã¢ã¯ãFP64è¡åãè€æ°ã®äœç²ŸåºŠè¡åã«åè§£ããTensor Coreã§é«éã«è¡åç©ãèšç®ãããšãããã®ã§ããè¡åã®åè§£ãè¡åã®èšç®ãçµæã®çޝç©ã®3段éã§æ§æãããŸãã åè§£(Split) è«æã«åŸãã以äžã®åãå®çŸ©ããŸãã Type1 (FP64): å
ã®è¡åã®ç²ŸåºŠãä»®æ°éš $m_{\text{Type1}} = 53$ ããã Type2 : åè§£å
ã®äœç²ŸåºŠåïŒBF16, FP16, FP8çïŒãä»®æ°éš $m_{\text{Type2}}$ ãããïŒé ããããå«ãïŒ Type3 (FP32): Tensor Coreã®çޝç©ç²ŸåºŠãä»®æ°éš $m_{\text{Type3}} = 24$ ããã Type1ã®è¡å $\boldsymbol{x}$ ããæ®å·® $\boldsymbol{x}^{(p)}$ ããŒãã«ãªããŸã§ååž°çã«Type2ã¹ã©ã€ã¹ $\bar{\boldsymbol{x}}^{(p)}$ ã«åè§£ããŸãã$\boldsymbol{x}^{(1)} = \boldsymbol{x}$ ãšããŠãåã¹ããã $p$ ã§ä»¥äžãè¡ããŸãã $$c_x^{(p)} = \left\lceil \log_2 \left( \max_i \left| x_i^{(p)} \right| \right) \right\rceil \tag{1}$$ $$\sigma = 0.75 \cdot 2^{\rho + c_x^{(p)}} \tag{2}$$ $$v_i = \text{fl}_{\text{Type1}} \left( \left( x_i^{(p)} + \sigma \right) - \sigma \right) \tag{3}$$ $$x_i^{(p+1)} = \text{fl}_{\text{Type1}} \left( x_i^{(p)} - v_i \right) \tag{4}$$ $$\bar{x}_i^{(p)} = \text{cvt}_{\text{Type2}} \left( \text{fl}_{\text{Type1}} \left( 2^{-c_x^{(p)}} v_i \right) \right) \tag{5}$$ ããã§ $\rho$ ã¯ç²ŸåºŠãã©ã¡ãŒã¿ïŒType1, Type2, Type3ã®ä»®æ°éšãããæ°ãšå
ç©æ¬¡å
$k$ ããæ±ºå®ïŒã§ãã$\sigma$ ãè¶³ããŠåŒãæäœïŒåŒ3ïŒãVeltkampåå²ã®æ žå¿ã§ãäžäœ $m_{\text{Type2}}$ ããããæ£ç¢ºã«æœåºããŸããåŒ4ã§æ®å·®ãæŽæ°ããåŒ5ã§ $2^{c_x^{(p)}}$ ã§æ£èŠåããŠType2ã¹ã©ã€ã¹ãåŸãŸãã ãã®çµæã$\boldsymbol{x}$ 㯠$s_x$ åã®ã¹ã©ã€ã¹ã«åè§£ãããŸãã $$\boldsymbol{x} = \sum_{p=1}^{s_x} 2^{c_x^{(p)}} \cdot \bar{\boldsymbol{x}}^{(p)} \tag{9}$$ $c_x^{(p)}$ ãææ°éšã$\bar{\boldsymbol{x}}^{(p)}$ ãä»®æ°éšã«å¯Ÿå¿ããŸããã¹ã©ã€ã¹æ° $s_x$ 㯠$\boldsymbol{x}^{(p)} = 0$ ã«ãªããŸã§ã®ååŸ©åæ°ã§æ±ºãŸããçè«çã«ã¯ $\lceil m_{\text{Type1}} / m_{\text{Type2}} \rceil$ ã¹ãããã§ãããè¡åèŠçŽ ã®ã¹ã±ãŒã«ã®ã°ãã€ãã«ããå€ããªãããšããããŸãã PyTorchã§ã®å®è£
ã¯ä»¥äžã®éãã§ãã def ozaki_split_to_type2_slices (x, k, type2, max_slices= 20 ): # ä»®æ°éšãããæ°ïŒé ããããå«ãïŒ m_fp64, m_fp32 = 53 , 24 m_type2 = - int (math.log2(torch.finfo(type2).eps)) + 1 # 粟床ãã©ã¡ãŒã¿ Ï ã®èšç® gamma = math.ceil(m_fp64 - (m_fp32 - math.log2(k)) / 2 ) xi = m_fp64 - m_type2 rho = max (gamma, xi) slices = [] residual = x.clone().to(torch.float64) for _ in range (max_slices): max_abs = residual.abs().max().item() if max_abs == 0 or max_abs < 1e-300 : break c_x = math.ceil(math.log2(max_abs)) # åŒ(1) sigma = 0.75 * math.ldexp( 1.0 , rho + c_x) # åŒ(2) v = (residual + sigma) - sigma # åŒ(3) Veltkampåå² residual = residual - v # åŒ(4) æ®å·®æŽæ° scale = math.ldexp( 1.0 , c_x) slice_type2 = (v / scale).to(type2) # åŒ(5) æ£èŠå + Type2倿 slices.append((slice_type2, scale)) return slices # [(Type2ã¹ã©ã€ã¹, 2^c_x), ...] è¡åç©ã®èšç® è¡å $\boldsymbol{x}$, $\boldsymbol{y}$ ãããããåè§£ãããšãè¡åç©ã¯ä»¥äžã®ããã«å±éã§ããŸãã $$\boldsymbol{x}^T \boldsymbol{y} = \sum_{p=1}^{s_x} \sum_{q=1}^{s_y} 2^{c_x^{(p)} + c_y^{(q)}} \cdot \bar{\boldsymbol{x}}^{(p)T} \bar{\boldsymbol{y}}^{(q)} \tag{10}$$ å $\bar{\boldsymbol{x}}^{(p)T} \bar{\boldsymbol{y}}^{(q)}$ ã¯Type2è¡åå士ã®ç©ã§ãããTensor Coreã®GEMMã§èšç®ã§ããŸããOzaki Schemeã§ã¯Ïãã©ã¡ãŒã¿ã«ããããã®GEMMã®Type3ïŒFP32ïŒã§ã®çޝç©ãäžžã誀差ãªãã§æç«ããããèšèšãããŠããŸãã $$\bar{\boldsymbol{x}}^{(p)T} \bar{\boldsymbol{y}}^{(q)} = \text{fl}_{\text{Type3}} \left( \bar{\boldsymbol{x}}^{(p)T} \bar{\boldsymbol{y}}^{(q)} \right) \tag{11}$$ åŒ10ã®åè§£èªäœã¯æ°åŠçãªæçåŒãšããŠå³å¯ã«æç«ããŸããå®è£
äžã¯ãå€åŽã®çޝç©ïŒã¹ã±ãŒã«ä¹ç®ãšå ç®ïŒãType1ç®è¡ã§è¡ãããšã§Type1粟床ãéæã§ããŸãã cuTileã§ã®è¡åç©ã«ãŒãã«ã®å®è£
ã¯ä»¥äžã®éãã§ããtilegymã®matmulã«ãŒãã«ãšããŒã¹ã¯åãã§ïŒã€ã®ã¹ã©ã€ã¹åã®outer-loopã远å ãããŠããŸãã @ ct.kernel (num_ctas=ct.ByTarget(sm_100= 2 )) def ozaki_matmul_fused_kernel ( A_slices, # (s_a, M, K) Type2ã¹ã©ã€ã¹ B_slices, # (s_b, K, N) Type2ã¹ã©ã€ã¹ Combined_scales, # (s_a, s_b) 2^{c_x(p)+c_y(q)} ã®ã¹ã±ãŒã«è¡å C, # (M, N) FP64 åºå TILE_SIZE_M: ConstInt, TILE_SIZE_N: ConstInt, TILE_SIZE_K: ConstInt, ): # ã¿ã€ã«ã€ã³ããã¯ã¹èšç®ïŒL2ãã£ãã·ã¥å±ææ§ã®ããswizzleïŒ bidx, bidy = swizzle_2d(M, N, TILE_SIZE_M, TILE_SIZE_N, GROUP_SIZE_M= 8 ) num_tiles_k = ct.cdiv(K, TILE_SIZE_K) # FP64æçµã¢ãã¥ã ã¬ãŒã¿ïŒåŒ10ã®å€åŽã®çޝç©ïŒ accumulator = ct.full((TILE_SIZE_M, TILE_SIZE_N), 0.0 , dtype=ct.float64) # å
šã¹ã©ã€ã¹ã㢠(p, q) ãã«ãŒã for p in range (num_slices_a): for q in range (num_slices_b): # FP32äžéã¢ãã¥ã ã¬ãŒã¿ïŒåŒ11: Type3ã§ã®äžžã誀差ãªãèšç®ïŒ slice_acc = ct.full((TILE_SIZE_M, TILE_SIZE_N), 0.0 , dtype=ct.float32) # Kæ¹åã®ã¿ã€ã«ã«ãŒã for k in range (num_tiles_k): a_tile = ct.load(A_slices, index=(p, bidx, k), ...) b_tile = ct.load(B_slices, index=(q, k, bidy), ...) slice_acc = ct.mma(a_tile, b_tile, slice_acc) # Type2 Tensor Core MMA # ã¹ã±ãŒãªã³ã°ããŠFP64ã§çޝç©ïŒåŒ10ïŒ scale = ct.load(Combined_scales, index=(p, q), shape=( 1 , 1 )) accumulator = accumulator + ct.astype(slice_acc, ct.float64) * scale ct.store(C, index=(bidx, bidy), tile=accumulator) çŽ æŽãªå®è£
ãšååçµæ äžèšã®ããã«Ozaki Schemeãå®è£
ããŠã¿ãŸããã¹ã©ã€ã¹åå²ã¯ãã¹ãåŽã®pythonã§è¡ããåãã¢ã®GEMMãé æ¬¡å®è¡ããæ¹åŒã§ãã以äžã2çš®é¡ã®Type2ã§è¡åç©ãèšç®ããçµæã§ãã ã¹ã©ã€ã¹æ°ã¯Aã»Bããããã®å岿°ïŒ$s_a \times s_b$ïŒãGEMMsã¯ãã®çµã¿åããã§å®è¡ããGEMMåæ°ã§ããTFLOPSã¯FP64æç®ã®ã¹ã«ãŒããããRel Errorã¯PyTorch FP64çµæãåºæºãšããçžå¯Ÿèª€å·®ã§ãã TYPE2 = FP16 è¡åãµã€ãº ã¹ã©ã€ã¹æ° GEMMs Split(ms) Kernel(ms) åèš(ms) TFLOPS Rel Error 1024 10Ã10 100 1.48 0.62 2.64 0.81 1.58e-15 2048 12Ã12 144 2.57 2.66 5.75 2.99 1.98e-15 4096 12Ã12 144 8.69 21.59 30.70 4.48 6.31e-15 8192 14Ã14 196 36.00 192.32 231.76 4.74 7.28e-15 16384 14Ã14 196 135.21 1737.14 1884.24 4.67 3.35e-15 TYPE2 = FP8 (E4M3) è¡åãµã€ãº ã¹ã©ã€ã¹æ° GEMMs Split(ms) Kernel(ms) åèš(ms) TFLOPS Rel Error 1024 15Ã16 240 2.22 1.11 4.03 0.53 1.64e-15 2048 16Ã16 256 3.48 3.11 7.33 2.34 2.27e-15 4096 16Ã17 272 12.30 19.17 30.86 4.45 5.69e-15 8192 17Ã17 289 45.64 179.99 226.64 4.85 8.88e-15 FP16ã¯ã¹ã©ã€ã¹æ°ãå°ãªãåGEMMãå°ãªããªããŸãããFP8ã¯Tensor Coreã®ã¹ã«ãŒããããé«ããããGEMMsæ°ãå€ãã«ãé¢ãããé¡äŒŒã®æ§èœãåºãŠããŸãããããã®åã§ãcuTile FP64çŽæ¥èšç®ïŒçŽ1 TFLOPSïŒãäžåã£ãŠããŸãããPyTorchã®æ§èœã«ã¯å€§ããå£åŸããŠããŸããSplitåŠçã®æéãç¡èŠã§ãããç¹ã«å°ããªè¡åãµã€ãºã§ããã«ããã¯ã«ãªã£ãŠããŸãããŸããåç
§ããè«æã«èšèŒãããŠããå¿
èŠãªGEMMæ°(ã¹ã©ã€ã¹æ°ïŒãããå€ããªã£ãŠããç¹ã¯æ°ã«ãªããŸããããåå ã¯ããããã§ããã æé©å ååçµæãèžãŸããããã€ãæ¹åã詊ã¿ãŸããããã®äžã§å¹æããã£ãæ¹æ³ã以äžã«ãªããŸãã Fast ModeïŒGEMMã®åæžïŒ ã¹ã©ã€ã¹æ°ã $s$ ã®å Žåãå
šçµã¿åããã§ $s^{2}$ åã®GEMMãå¿
èŠã§ããããããã¹ã©ã€ã¹ã€ã³ããã¯ã¹ã倧ããçµã¿åããïŒ$i + j \geq d$ïŒã¯å¯äžãå°ãããããã¹ãããã§ããŸãã [5]ã§ææ¡ãããFast ModeïŒAlgorithm 3ïŒã§ã¯ã確çç誀差éç $|fl(AB) - AB| \leq 2\sqrt{k} \cdot u_{\text{FP64}} \cdot |A||B|$ ãæºããæå°ã®éŸå€ $d$ ãèªå決å®ããŸãã BF16ã®å Žåãå
žåçã«ã¯ $d = 9$ çšåºŠã§ãGEMMã¯49åãã39åã«åæžã§ããŸããããã« max_d ãã©ã¡ãŒã¿ã§æåäžéãèšå®ããã°ã粟床ãšã®ãã¬ãŒããªãã§èšç®éã調æŽã§ããŸãã å®è£
ãšããŠã¯ãåè¿°ã®è¡åç©ã«ãŒãã«ã®ã¹ã©ã€ã¹ãã¢ã«ãŒãã« i + j >= D ã®æ¡ä»¶ã远å ããã ãã§ãã for i in range (num_slices_a): for j in range (num_slices_b): if i + j >= D: # Fast Mode: å¯äžã®å°ããçµã¿åãããã¹ããã continue # ... Kæ¹åã«ãŒãã§MMAèšç® ... Fused Split KernelïŒåå²ã®èåïŒ å
ã®å®è£
ã§ã¯ãåã¹ã©ã€ã¹ã®èšç®ããšã« max().item() ã§GPUâCPUåæãçºçããŠããŸããïŒBF16ã§7ã¹ã©ã€ã¹ = 7åã®åæïŒã æ¹ååŸã¯ãååã® max_abs èšç®ã§1åã ãåæããå
šã¹ã©ã€ã¹ã® $\sigma$ ãš $2^{-c_i}$ïŒéã¹ã±ãŒã«ïŒãCPUåŽã§äºåèšç®ããŸãããã®åŸãåäžã«ãŒãã«ã§å
šã¹ã©ã€ã¹ãäžæ¬èšç®ããŸãã @ ct.kernel (occupancy= 4 ) def _veltkamp_split_all_slices_kernel ( x_in, # (M, N) FP64 input slices_out, # (num_slices, M, N) TYPE2 output slices sigmas, # (num_slices,) FP64 pre-computed sigma values inv_scales, # (num_slices,) FP64 pre-computed 1/scale values num_slices: ConstInt, TILE_SIZE_M: ConstInt, TILE_SIZE_N: ConstInt, ): bid = ct.bid( 0 ) # ... (ã¿ã€ã«ã€ã³ããã¯ã¹èšç®) ... # å
¥åã¿ã€ã«ãããŒã residual = ct.load(x_in, index=(tile_m, tile_n), shape=(TILE_SIZE_M, TILE_SIZE_N), padding_mode=ct.PaddingMode.ZERO) # å
šã¹ã©ã€ã¹ãã«ãŒãã§èšç® for i in range (num_slices): sigma_tile = ct.load(sigmas, index=(i,), shape=( 1 ,)) inv_scale_tile = ct.load(inv_scales, index=(i,), shape=( 1 ,)) # Veltkampåå² v = (residual + sigma_tile) - sigma_tile slice_tile = ct.astype(v * inv_scale_tile, slices_out.dtype) ct.store(slices_out, index=(i, tile_m, tile_n), tile=ct.reshape(slice_tile, ( 1 , TILE_SIZE_M, TILE_SIZE_N))) residual = residual - v æé©ååŸã®çµæ Fast Mode + Fused Split Kernelãé©çšããçµæã§ãã TYPE2 = BF16 è¡åãµã€ãº ã¹ã©ã€ã¹æ° GEMMs Split(ms) Kernel(ms) åèš(ms) TFLOPS Rel Error 1024 7Ã7 39 0.20 0.25 1.57 1.37 5.75e-15 2048 7Ã7 39 0.24 0.75 2.16 7.94 1.30e-14 4096 7Ã7 39 0.43 5.32 7.22 19.04 1.16e-14 8192 7Ã7 39 1.16 38.93 42.60 25.81 2.39e-14 16384 7Ã7 39 3.96 323.10 327.78 26.84 2.21e-14 TYPE2 = FP8 (E4M3) è¡åãµã€ãº ã¹ã©ã€ã¹æ° GEMMs Split(ms) Kernel(ms) åèš(ms) TFLOPS Rel Error 1024 14Ã14 130 0.25 0.61 2.99 0.72 3.48e-13 2048 14Ã14 130 1.27 1.60 6.80 2.52 3.57e-13 4096 14Ã14 130 2.13 9.31 15.88 8.65 3.41e-13 FP8ã¯ã¹ã©ã€ã¹æ°ãå€ãïŒ14Ã14ïŒGEMMsã130åãšå€ããã®ã®ãFast Modeã«ããGEMMåæžãšFused Splitã®å¹æã§çŽ æŽãªå®è£
ïŒ4096ã§4.45 TFLOPSïŒããæ¹åãèŠãããŸãããã ãBF16ãšæ¯èŒãããšãä»®æ°éšã4ããããšå°ãªãããã¹ã©ã€ã¹æ°ãå¢ããGEMMsæ°ã®å·®ïŒ130 vs 39ïŒãFP8ã®ã¹ã«ãŒãããåªäœãæã¡æ¶ããŠãããBF16ã®æ¹ãç·åçã«æå©ã«ãªããŸããã çŽ æŽãªå®è£
ãšæ¯èŒãããšãæé©åã®å¹æã¯é¡èã§ãã Fused Split Kernel : Splitæéã倧å¹
ççž®ïŒçŽ æŽãªFP16ç 8192: 36.00ms â BF16æé©åç: 1.16msãçŽ31åïŒ Fast Mode : GEMMsã49â39ã«åæžïŒBF16ã®å
šçµã¿åããæ¯ïŒ BF16ãTYPE2ãšããŠæé©ã§ããçç±ã¯ãTensor Coreã®FP32ã¢ãã¥ã ã¬ãŒã¿ãšã®çžæ§ã«ãããŸããBF16ã®ä»®æ°éšã¯8ããããªã®ã§ã2ã€ã®BF16å€ã®ç©ã¯16ãããã«åãŸããŸããFP32ã®ä»®æ°éšã¯24ããããããããTILE_SIZE_K=128åã®ç©åïŒ16 + log2(128) = 23 †24ïŒã äžžã誀差ãªã ã§æ£ç¢ºã«èšç®ã§ããŸããäžæ¹FP16ïŒ11ãããä»®æ°éšïŒã§ã¯ç©ã22ããããšãªãã128åã®çޝç©ïŒ22 + 7 = 29 > 24ïŒã§FP32粟床ãè¶
ãããããäžžã誀差ãçºçããŸãã ãã®æ§è³ªã«ãããBF16ã§ã¯1e-14ãšããFP64ã«è¿ã粟床ãç¶æãã€ã€ãTensor Coreã®é«ãã¹ã«ãŒããããæŽ»çšã§ããŠããŸãã äžèšä»¥å€ã«ããã¿ã€ã«ãµã€ãºã®èª¿æŽããã«ãŒãã«å
ã®splitã«ãŒãæ¹åã®CTA忣ã詊ã¿ãŸãããã广ã¯ãããŸããã§ãããæ¬æ¥ã¯ããããã¡ã€ã©ïŒNVIDIA Nsight ComputeïŒã䜿ã£ãŠãã¡ã¢ãªå©çšçè§£æããã®ã广çã§ãããModaläžã§ã¯Nsightã¯äœ¿ããªããããªã®ã§æå¿µããŸããã dã«ãã粟床/é床ãã¬ãŒããªã d ãã©ã¡ãŒã¿ãå€ããŠã16384Ã16384è¡åã§ã®æ§èœãšç²ŸåºŠã®å€åãæž¬å®ããŸãããBF16ã®çµæã§ãã d GEMMs åèš(ms) TFLOPS Rel Error vs PyTorch FP64 9 (default) 39 327.78 26.84 2.21e-14 0.75x 8 34 298.76 29.44 2.31e-14 0.83x 7 28 238.94 36.81 3.50e-13 1.03x 6 21 189.59 46.40 4.39e-11 1.30x 5 15 136.34 64.52 4.51e-09 1.81x PyTorch FP64ïŒcuBLASïŒã¯åãµã€ãºã§35.62 TFLOPSã§ããRel Errorã¯PyTorch FP64ã®çµæãåºæºãšããŠèšç®ããŠããŸãã d=7 ã§cuBLASãšåçã®é床ã粟床1e-13ã§éæãã d=5 ã§ã¯1.8åã®é«éåã1e-9粟床ã§å®çŸããŠããŸãããªããFP64 GEMMèªäœãæµ®åå°æ°ç¹æŒç®ã®æ§è³ªäžãè¡åãµã€ãºã«å¿ããäžžã誀差ã¯é¿ããããªãããã d=8 ïŒ2.31e-14ïŒçšåºŠã®åå·®ã§ããã°å®çšäžååã§ãããã ãŸãšã cuTile Pythonã®ç°¡åãªç޹ä»ãšOzaki Schemeã®å®è£
ãéããŠãFP64è¡åç©ã®é«éåã詊ã¿ãŸãããBF16 Ozaki Schemeã®æé©ååŸã16384Ã16384è¡åã§æå€§26.84 TFLOPSïŒd=9ïŒãéæããŸãããdã調æŽããããšã§ç²ŸåºŠãšé床ã®ãã¬ãŒããªããå¯èœã§ãd=7ã§ã¯cuBLAS FP64ïŒ35.62 TFLOPSïŒãšåçã®36.81 TFLOPSã粟床1e-13ã§éæããd=5ã§ã¯64.52 TFLOPSïŒcuBLASã®1.8åïŒã1e-9粟床ã§å®çŸããŠããŸãã CUDAã«ãŒãã«ãPythonã©ã€ã¯ã«æžããç¹ã§ãGPUããã°ã©ãã³ã°ã®æ·å±
ãäœããªã£ããšæããŸãã äžæ¹ã§ãããé«åºŠãªæé©åããã¥ãŒãã³ã°ãå¿
èŠãªå Žåã¯ãcuTile Pythonã¯æœè±¡åããŠããŒãåŽã®è©³çްãé èœããŠããåãå¶çŽãããããã«æããŸãããä»åã¯ãè¡åç©ã®äŸã§ããããtilegymã«ã¯transformerã®å®è£
äŸãããã®ã§ã次åã¯ãã¡ãã詊ããŠã¿ãããšæããŸãã åèæç® [1] Lecture 89: cuTile (from friends at NVIDIA) [2] NVIDIA cuTile Documentation . cuTile Python. [3] NVIDIA TileGym . GPU Tile kernel development examples using cuTile. [4] Markus Höhnerbach, Paolo Bientinesi (2025). "DGEMM without FP64 Arithmetic" . arXiv:2508.00441. [5] Daichi Mukunoki, Katsuhisa Ozaki, Takeshi Ogita, and Toshiyuki Imamura (2020). "DGEMM using Tensor Cores, and Its Accurate and Reproducible Versions". ISC High Performance 2020, Lecture Notes in Computer Science, Vol. 12151. Springer, 230â248. doi:10.1007/978-3-030-50743-5_12
ã¯ããã« ããã«ã¡ã¯ãZOZOTOWNéçºæ¬éšããã³ããšã³ãã®èå°ïŒ @hiro0218 ïŒã§ãã 2021幎ãZOZOTOWNã¯ããã³ããšã³ããªãã¬ã€ã¹ãéå§ããŸãããçŸåšãããŒã ããŒãžãååäžèЧããŒãžãªã©äž»èŠãªããŒãžã®Next.jsåãå®äºããéçšãã§ãŒãºã«å
¥ã£ãŠããŸãã詳现ã¯ä»¥äžã®èšäºãåç
§ããŠãã ããã techblog.zozo.com éå§åœåãä»ç€ŸäºäŸãåèã«ããªããããããã課é¡ãæªç¶ã«é²ããã£ã¬ã¯ããªæ§æãèšèšããŸãããæ¬èšäºã§ã¯ãçŽ4幎ã«ãããéçšã§æ¹åãéããŠãããã£ã¬ã¯ããªã®å岿Šç¥ã«ã€ããŠç޹ä»ããŸãã â»æ¬èšäºã¯2025幎8æã«ã¡ãã£ãšæ ªåŒäŒç€Ÿãšã®ååå匷äŒã§çºè¡šããå
容ãåºã«ããŠããŸãã speakerdeck.com èæ¯ çŸåšãç§ãæºãã£ãŠããé åã«ãããããã³ããšã³ãéçºã¯4ããŒã ãåèš30å匷ã§éçšããŠããŸãããã®èŠæš¡ã§å¹ççã«éçºãé²ããããããã£ã¬ã¯ããªæ§æã¯éèŠãªèŠçŽ ãšãªããŸãã é¿ãããèª²é¡ éå»ã®çµéšãä»ç€ŸäºäŸããã以äžã®ãããªèª²é¡ãæªç¶ã«é²ãå¿
èŠããããŸããã é
çœ®å Žæãææ§ïŒããªããšãªãããã«çœ®ãããã³ã³ããŒãã³ããå¢ããåŸããèŠã€ãã«ãã åå©çšæ§ãäœãïŒããŒãžåºæã®åŠçãå«ãã³ã³ããŒãã³ãã¯ãä»ã®ããŒãžã§äœ¿ãã«ãã 圱é¿ç¯å²ãäžæç¢ºïŒã³ã³ããŒãã³ãã倿Žããéãã©ãã§äœ¿ãããŠãããææ¡ãã¥ãã ããŒã éçºãéå¹çïŒã¡ã³ããŒããšã«é
眮ã«ãŒã«ã®è§£éãç°ãªããã³ãŒãã¬ãã¥ãŒã§è¿·ã æ°èŠéçºã«ããããããããèæ
®ããèšèšæŠç¥ãæ¡çšããŸããã 解決ã¢ãããŒãïŒè²¬ååé¢ãã¿ãŒã³ 圹å²ãæç¢ºã«ããé
眮ïŒè²¬ååé¢ïŒãè¡ããŸããããã®èšèšãéžãã çç±ã¯ãè¿·ããªãåé¡ãã§ããæ°ããã³ã³ããŒãã³ããäœæããéãé
çœ®å Žæã§è¿·ãæéãæå°åããã¡ã³ããŒéã§å€æãåãããªãããã«ããããšãéèŠããŸããã ãã®èšèšã§ã¯ã以äžã®2ç¹ãéèŠããŠããŸãã éçšäžã®ç§»åæå°å : äžåºŠé
眮ããã³ã³ããŒãã³ãã¯ãåºæ¬çã«ç§»åãäžèŠ äºæž¬å¯èœãªæ§é : ãã£ã¬ã¯ããªéå±€ãæ·±ããªãããæ¢çŽ¢ãããã ãã®èšèšãå®çŸããããã以äžã®2å±€æ§é ãæ¡çšããŸããã ã³ã³ããŒãã³ãå±€ ïŒ src/components/ ïŒ åœ¹å²å¥ã«5ã€ã®ãã£ã¬ã¯ããªã«åé¡ UI ã€ã³ãã©å±€ ïŒ src/ui/ ïŒ ã³ã³ããŒãã³ããå©çšããå
±éåºç€ ã³ã³ããŒãã³ãå±€ã®å®è£
ãé²ããäžã§ãUIã€ã³ãã©å±€ã®å¿
èŠæ§ãèŠããŠããŸããã ã³ã³ããŒãã³ã局㚠UI ã€ã³ãã©å±€ã®é¢ä¿ ã³ã³ããŒãã³ãå±€ã®èšèš ã³ã³ããŒãã³ãã5ã€ã®åœ¹å²ã«åé¡ããããããã®è²¬åãšäŸåé¢ä¿ãå®çŸ©ããŠããŸãã ãã£ã¬ã¯ããªæ§æ ä»ç€ŸäºäŸãåèã«ããŠ5ã€ã®ãã£ã¬ã¯ããªã«åå²ããæ§æãæ¡çšããŸããã src/components/ âââ UI/ âââ Models/ âââ Pages/ âââ Layouts/ âââ Functional/ Next.jsã®ã«ãŒãã£ã³ã°çšãã£ã¬ã¯ããªïŒ src/pages ïŒãšåºå¥ãããããé ã倧æåãšããŠããŸãã 責åããšã®åé¡ åãã£ã¬ã¯ããªã®åœ¹å²ã¯ä»¥äžã®ããã«å®çŸ©ãããŠããŸãã åå åœ¹å² æ ŒçŽããã³ã³ããŒãã³ãäŸ UI çŽç²ãªUIèŠçŽ Button, Collapse, Image... Models ãã¡ã€ã³ããžãã¯ããã ProductList, BrandList... Pages ããŒãžå°çš HomePage, SearchPage... Layouts ã¢ããªã«é¢ããã¬ã€ã¢ãŠã Header, Footer... Functional UIã䌎ããªãã¢ããªã±ãŒã·ã§ã³æ©èœ Analytics, GlobalStore... ãã®åé¡ã®ãã€ã³ãã¯ãæ°ããã³ã³ããŒãã³ããäœããšããã©ãã«é
眮ãããè¿·ããªããããšã§ããææ§ãªå€æåºæºã§ã¯ãã¡ã³ããŒããšã«è§£éãåãããã¬ãã¥ãŒæã®è°è«ã³ã¹ããå¢å€§ããŸãã ã³ã³ããŒãã³ãäœææã®å€æãã㌠ã³ã³ããŒãã³ããäœæããéã¯ã以äžã®é ã§å€æããŸãã ç¹å®ã®ããŒãžã§ã®ã¿äœ¿çšãããïŒ YES â src/components/Pages/ ã«é
眮 å€æåºæºïŒä»ã®ããŒãžã§ã¯åå©çšãããªãåºæã®å®è£
äŸïŒHomePageãSearchPage ã¢ããªå
šäœã®ã¬ã€ã¢ãŠãæ§é ã«é¢ãããïŒ YES â src/components/Layouts/ ã«é
眮 å€æåºæºïŒã¢ããªå
šäœã®æ§é ã»éªšæ Œãæ
åœ äŸïŒHeaderãFooter ç¹å®ã®ãã¡ã€ã³ããžãã¯ãå«ã¿è€æ°ããŒãžã§äœ¿çšãããïŒ YES â src/components/Models/ ã«é
眮 å€æåºæºïŒç¹å®ã®ãã¡ã€ã³ã«é¢é£ããæ©èœãæã€ã³ã³ããŒãã³ã äŸïŒProductListãBrandList UIã®ã¿ã®æ±çšçãªã³ã³ããŒãã³ããïŒ YES â src/components/UI/ ã«é
眮 å€æåºæºïŒããžãã¹ããžãã¯ãå«ãŸãªãçŽç²ãªUIèŠçŽ äŸïŒButtonãCollapseãImage éèŠïŒãã¡ã€ã³åºæã®ååãæã€ã³ã³ããŒãã³ãããããŒã¿ã衚瀺ããã ããªãUIã«é
眮ãModelsãšã®éã㯠ããŒã¿ååŸãããžãã¹ã«ãŒã«ãå«ããã©ãã UIã䌎ããªãã¢ããªã±ãŒã·ã§ã³æ©èœãïŒ YES â src/components/Functional/ ã«é
眮 å€æåºæºïŒçŽæ¥ãŠãŒã¶ãŒã«è¡šç€ºãããªãã¢ããªã±ãŒã·ã§ã³æ©èœ äŸïŒAnalyticsãGlobalStore å®è£
äŸ UIã¯çŽç²ãªè¡šç€ºãModelsã¯ãã¡ã€ã³ããžãã¯ãšãã責åã®åé¢ããå®éã®ã³ãŒãã§ç¢ºèªããŸãã UI ã³ã³ããŒãã³ã propsã§åãåã£ãããŒã¿ã衚瀺ããã ãã®ã·ã³ãã«ãªå®è£
ã§ãã // UI/ProductCard - UI ã³ã³ããŒãã³ã export const ProductCard = ( { name , price , image } ) => ( < Card > < Image src = { image } /> < Title > { name } </ Title > < Price > { price } </ Price > </ Card > ); Models ã³ã³ããŒãã³ã ããŒã¿ãååŸããUIã³ã³ããŒãã³ããçµã¿åãããŠè¡šç€ºããŸãã // Models/ProductList - ãã¡ã€ã³ããžã㯠+ UI ãå©çš export const ProductList = ( props ) => { const { products } = useProductData(props); return ( < Grid > { products?. map (( product ) => ( < ProductCard key = { product. id } { ...product } /> )) } </ Grid > ); } ; ProductCard ïŒUIïŒã¯çŽç²ãªè¡šç€ºã ProductList ïŒModelsïŒã¯ããŒã¿ååŸãšUIã®çµã¿åãããšãã責åã®éããåãããŸãã ãã¹ããã¡ã€ã«ã®é
眮 ã³ã³ããŒãã³ãã®åé¡ãšåæ§ã«ããã¹ããã¡ã€ã«ã®é
眮ãã«ãŒã«ãå¿
èŠã§ãããã¹ããStorybookã®ãã¡ã€ã«ã¯ã察象ã®ã³ã³ããŒãã³ããã¡ã€ã«ãšåããã£ã¬ã¯ããªã«é
眮ããããšã§ãé¢é£ãããã¡ã€ã«ãäžç®æã«ãŸãšããŠç®¡çããŠããŸãã components/UI/Button/ âââ Button.tsx âââ Button.test.tsx âââ Button.stories.tsx âââ Button.module.css ãã®é
眮ã«ãããå®è£
ãšãã¹ãã®å¯Ÿå¿é¢ä¿ãåããããããªãããã¡ã€ã«éã®ç§»åãã¹ã ãŒãºã«ãªããŸãã äŸåé¢ä¿ã®ã«ãŒã« ã³ã³ããŒãã³ãéã®äŸåé¢ä¿ã¯ãèªåã®æšªãäžã«ããåé¡ã®ã³ã³ããŒãã³ãã®ã¿åç
§ããŠããããšããååã«åŸããŸãã äŸåã®åºæ¬ååïŒäžäœããäžäœãžã®äžæ¹åã®ã¿èš±å¯ã Pages ïŒ src/components/Pages ïŒ: ModelsãUIãFunctionalãåç
§å¯èœ Modelsã»Layouts : UIãšFunctionalãåç
§å¯èœ UI : Functionalã®ã¿åç
§å¯èœ Functional : å€éšäŸåãªãïŒæäžäœïŒ åãã£ã¬ã¯ããªã¯ãåããã£ã¬ã¯ããªå
ã®ã³ã³ããŒãã³ãå士ãåç
§å¯èœã§ãïŒPagesãé€ãïŒã æ³šèš : ããã§ã®ãPagesã㯠src/components/Pages ïŒããŒãžå°çšã³ã³ããŒãã³ãïŒãæããŸããNext.jsã®ã«ãŒãã£ã³ã°çšãã£ã¬ã¯ããªã§ãã src/pages ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãŒãã€ã³ããšããŠç¹å¥ãªåœ¹å²ãæã€ãããLayoutsãå«ããã¹ãŠã®ã³ã³ããŒãã³ããåç
§å¯èœã§ãã ãã®äŸåé¢ä¿ã«ããã埪ç°åç
§ãé²ãã倿Žã®åœ±é¿ç¯å²ãäºæž¬ãããããªããŸãã äŸåé¢ä¿ã®ãã§ã㯠èšèšãããã£ã¬ã¯ããªæ§æã®ã«ãŒã«ãå®ãããããã以äžã®ããŒã«ãå°å
¥ããŠããŸãã ãã£ã¬ã¯ããªéã®äŸåã«ãŒã« eslint-plugin-strict-dependencies ã«ããã誀ã£ãäŸåé¢ä¿ãèªåçã«æ€åºããã³ãŒãã¬ãã¥ãŒæã®è² æ
ã軜æžããŠããŸãã 'strict-dependencies/strict-dependencies' : [ 'error' , [ // Pages ã³ã³ããŒãã³ãã®äŸåã«ãŒã« { module : 'src/components/Pages' , allowReferenceFrom : [ 'src/pages' ] , // Next.jsã®ã«ãŒãã£ã³ã°çšãã£ã¬ã¯ããªããã®ã¿åç
§å¯èœ allowSameModule : false , } , // Models ã³ã³ããŒãã³ãã®äŸåã«ãŒã« { module : 'src/components/Models' , allowReferenceFrom : [ 'src/components/Pages' ] , allowSameModule : true , } , // Layouts ã³ã³ããŒãã³ãã®äŸåã«ãŒã« { module : 'src/components/Layouts' , allowReferenceFrom : [ 'src/pages' ] , // Next.jsã®ã«ãŒãã£ã³ã°çšãã£ã¬ã¯ããªããã®åç
§ãèš±å¯ allowSameModule : true , } , // UI ã³ã³ããŒãã³ãã®äŸåã«ãŒã« { module : 'src/components/UI' , allowReferenceFrom : [ 'src/pages' , // Next.jsã®ã«ãŒãã£ã³ã°çšãã£ã¬ã¯ã㪠'src/components/Pages' , // ããŒãžå°çšã³ã³ããŒãã³ã 'src/components/Layouts' , 'src/components/Models' , ] , allowSameModule : true , } , // ïŒçç¥ïŒä»ã«ã倿°ã®ã«ãŒã«ãå®çŸ©... ] ] Pages ãã£ã¬ã¯ããªã®ç¹æ®ãªèšå® äžèšã®èšå®ã«ãããŠãPagesãã£ã¬ã¯ããªïŒ src/components/Pages ïŒã®ã¿ allowSameModule: false ãæ¡çšããŠããŸããããã¯ãããŒãžéã®ç¬ç«æ§ãä¿èšŒããããã®èšèšã§ãã Pagesãã£ã¬ã¯ããªã¯ Cart/ ã Home/ ã Search/ ã®ããã«ããŒãžããšã«ãµããã£ã¬ã¯ããªãåãããŠãããåããŒãžå°çšã®ã³ã³ããŒãã³ããé
眮ãããŠããŸãã allowSameModule: false ã«ãããããããŒãžã®ã³ã³ããŒãã³ããå¥ã®ããŒãžã®ã³ã³ããŒãã³ããåç
§ããããšãçŠæ¢ããŠããŸãã // NG: Cart ããŒãžã Home ããŒãžã®ã³ã³ããŒãã³ããåç
§ import { HomeComponent } from "../Home/HomeComponent" ; ããè€æ°ã®ããŒãžã§äœ¿ãããã³ã³ããŒãã³ããåºãŠããå Žåãæ¬æ¥ã¯ModelsãUIãLayoutsã®ããããã«é
眮ãã¹ãã³ã³ããŒãã³ãã§ããå¯èœæ§ãé«ããããé©åãªãã£ã¬ã¯ããªãžã®ç§»åãæ€èšããŸãã 埪ç°åç
§ã®ãã§ã㯠dependency-cruiser ãå°å
¥ããPRäžã§åŸªç°åç
§ãèªåæ€åºããŠããŸããããã«ãããè€éãªäŸåé¢ä¿ã«ããä¿å®æ§ã®äœäžãæªç¶ã«é²ãã§ããŸãã çŸåšã®éçšèŠæš¡ ãã®èšèšã§çŽ4幎ééçšããçµæãå·çæç¹ã§ã¯ä»¥äžã®ãããªèŠæš¡ã§ã³ã³ããŒãã³ããé
眮ãããŠããŸãã ãã£ã¬ã¯ã㪠å²å UI çŽ 50% Functional çŽ 20% Models çŽ 13% Pages çŽ 11% Layouts çŽ 6% UI ã€ã³ãã©å±€ã®èšèš ã³ã³ããŒãã³ãå±€ã§äœ¿çšããå
±éåºç€ãšããŠãã¹ã¿ã€ã«å®çŸ©ãããŒãã·ã¹ãã ã管çããŠããŸãã ãã£ã¬ã¯ããªæ§æ src/ui/ âââ themes/ # è²ã»mixinã»é¢æ°ã»ãã©ã³ãããŒãå®çŸ© â âââ mixin/ # Mixin ãã«ã㌠â âââ function/ # 颿°ãã«ã㌠â âââ themeVariants/ # ãã©ã³ãå¥ããŒã âââ styled/ # Emotion ã®ã¹ã¿ã€ã«é¢æ°çŸ€ âââ libs/ # UI ãŠãŒãã£ãªã㣠âââ constants/ # UI å
±é宿° âââ stylelint-plugins/ # ã«ã¹ã¿ã Stylelint ã«ãŒã« çµ±äžãããã¹ã¿ã€ã«å®çŸ© ZOZOTOWNã§ã¯CSS in JSïŒEmotionïŒãæ¡çšããŠããŸããSassãPostCSSã®ããã«mixinãfunctionãçšæãããããŒãšãã§ã¯ããã¿ã€ãã°ã©ãã£èšç®ãªã©ãã¹ã¿ã€ãªã³ã°ã®å
±éåŠçãæäŸããŠããŸãã const Button = styled.button ` ${ ( { theme } ) => theme.mixin.hoverOpacityEffect() } ; ` ; const Label = styled.span ` font-weight: ${ ( { theme } ) => theme.function.fontWeight( "bold" ) } ; ` ; å®è£
è
ã¯ã¹ã¿ã€ã«ã®è©³çްãæèãããäžè²«æ§ã®ããUIãæ§ç¯ã§ããŸãã å質æ
ä¿ Stylelintãã©ã°ã€ã³ã«ããã Emotionã®SSRå¶çŽ ïŒ :first-child çïŒã line-height ãªã©ããããžã§ã¯ãåºæã«ãŒã«ãèªåæ€èšŒããŠããŸãã ããŒãã·ã¹ãã ã®æŽ»çš ãããã®åºç€ã掻çšããå
·äœäŸãšããŠãZOZOTOWNã§ã¯ThemeProviderãçšããããŒãã·ã¹ãã ãå°å
¥ããŠããŸãã ãã©ã³ãããŒã ZOZOTOWNã«ã¯ãç¹å®ã®ãã©ã³ãåãã«ãã©ã³ãã«ã©ãŒãåæ ããŠããããŒãžããããŸãã察象ãã©ã³ãæ°ã¯å€ããããŸããããæ¡åŒµæ§ãèæ
®ããŠããŒãã·ã¹ãã ãå©çšããŠããŸãã const BRAND_COLOR = "#000" ; // ãã©ã³ãã«ã©ãŒ export const colors: ColorTheme = { button : { primary : { background : BRAND_COLOR } , } , text : { red : BRAND_COLOR, blue : BRAND_COLOR, } , } ; åããã«ãŒãã«å
¥ããããã¿ã³ã§ãããã©ã³ãããŒãžã§ã¯èªåçã«ãã®ãã©ã³ãåºæã®ã«ã©ãŒãé©çšãããŸãã ãµã€ããžã£ã㯠ãã©ã³ãåºåºã®æœçã§ããµã€ããžã£ãã¯ããšç§°ããŠãZOZOTOWNã®ã«ã©ãŒãæééå®ã§ãã©ã³ãã«ã©ãŒã«çœ®ãæããããšããããŸãã const JACK_COLOR = "#FF1493" ; // ãµã€ããžã£ãã¯ã«ã©ãŒ export const siteJackTheme: ColorTheme = { header : { background : JACK_COLOR } , navigation : { border : JACK_COLOR } , button : { primary : { background : JACK_COLOR } } , // ... } ; ãã®ããŒããé©çšãããšãZOZOTOWNã®ããããŒãããã²ãŒã·ã§ã³ãªã©ã®äž»èŠãªèŠçŽ ããæééå®ã§ãã©ã³ãåºæã®ã«ã©ãŒãžäžæ¬å€æŽã§ããŸãã ãŸãšã æ¬èšäºã§ã¯ãZOZOTOWNããã³ããšã³ãã«ããããã£ã¬ã¯ããªã®å岿Šç¥ã«ã€ããŠç޹ä»ããŸãããã³ã³ããŒãã³ãã5ã€ã®åœ¹å²ã«åé¡ãã倿ãããŒãšäŸåé¢ä¿ã®ã«ãŒã«ãèšããããšã§ãé
çœ®å Žæã§è¿·ããªãèšèšãå®çŸããŠããŸãããŸããèªåãã§ãã¯ã®ä»çµã¿ãUIã€ã³ãã©å±€ã®æŽåã«ãããäžè²«æ§ã®ããéçºç°å¢ãæ§ç¯ããŠããŸãã ãã¡ããããã¡ã€ã«æ°ã®å¢å ã«ããèŠçŽããæ€èšããŠããç®æãåºãŠããŠããŸããããããªãããåœåã®èšèšãã倧ããå€ãããšãå€§èŠæš¡éçºã«èãããåºç€ãç¶æã§ããŠãããæ°èŠã¡ã³ããŒãã¹ã ãŒãºã«éçºã«åå ã§ããç¶æ³ã§ãã責ååé¢ãæèãããã£ã¬ã¯ããªèšèšã¯ãé·æçãªéçºã«ãããŠæå¹ãªã¢ãããŒãã§ãããšå®æããŠããŸãã ZOZOã§ã¯ãäžç·ã«ãµãŒãã¹ãäœãäžããŠãããæ¹ãåéäžã§ãããèå³ã®ããæ¹ã¯ã以äžã®ãªã³ã¯ãããã²ãå¿åãã ããã corp.zozo.com
ããã«ã¡ã¯ãData&Analysiséš(D&A)ã§ãã D&Aã§ã¯é±1åãæ©æ¢°åŠç¿ã®å匷äŒãéå¬ããŠãããæ¬èšäºã¯ãå匷äŒã®å
容ãçæAIãæŽ»çšããŠèšäºã«ãŸãšãããã®ã§ãã â»å匷äŒå
容å
¬éã®çµç·¯ã¯ ãã¡ã â»éå»ã®å匷äŒã¯ã瀟å
å匷äŒãã¿ã°ãããã芧ããã ããŸãã ã¯ããã« LLMã·ã¹ãã ã¢ãŒããã¯ãã£ã®æŠèŠ ããã³ãããšã®äœéšãæäŸããLLMã·ã¹ãã RAG ãã¡ã€ã³ãã¥ãŒãã³ã° RAGãšãã¡ã€ã³ãã¥ãŒãã³ã°ã®äœµçš ãµã€ããšããŒã« ãµã€ã ããŒã« LLMã·ã¹ãã ãæ§ç¯ããéã®èæ
®äºé
ããã³ãåé¢ ã³ã¹ãèšç® ãã€ãžãŒãã€ã㌠ãŸãšã ã¯ããã« ä»åã¯ããã«ãããã³ãSasSã«ãããLLMã·ã¹ãã ã¢ãŒããã¯ãã£ã®æ¹éãšèæ
®äºé
ã«ã€ããŠèª¿æ»ããŸããã調æ»ã®çµç·¯ã¯ä»¥äžã®ãšããã§ãã ãã£ãã£ã§ã¯æ§ã
ãªããŒã¿ã«å¯ŸããŠLLMãæŽ»çšããæè¡æ€èšŒãé²ãã§ãããè¿ãå°æ¥CADDi Drawerãå§ããšãããã«ãããã³ãSaaSã«LLMãœãªã¥ãŒã·ã§ã³ãäœåãæäŸããå¯èœæ§ãããããã ãã®å°æ¥ã®å®çŸã®ããã«ãæ¬èšäºã§ã®ç޹ä»å
容ããããããèæ
®ããã·ã¹ãã ãèããŠããå¿
èŠããããšæããããã æ¬èšäºã§ã¯ã以äžã®è³æãåèã«ããŠããŸãã ãã«ãããã³ãSaaSã¢ãŒããã¯ãã£ã®æ§ç¯ 16ç« çæAIãšãã«ãããã³ã re:Invent 2024: AWSã®ãã«ãããã³ãSaaSã«ãããLLM掻çšã¢ãŒããã¯ã㣠LLMã·ã¹ãã ã¢ãŒããã¯ãã£ã®æŠèŠ LLMã·ã¹ãã ããã«ãããã³ãSaaSã§å±éããå Žåãã·ã³ãã«ãªæ§æãšããŠäžå³ã®ãããªãã®ãèããããŸãã ãã®å Žåãåãããã³ãããéä¿¡ããå Žååãã¬ã¹ãã³ã¹ããåŸãããŸããããã®ãããå瀟ïŒä»¥éãããã³ãïŒããšã®äœéšïŒäŸïŒç€Ÿå
è³æã«é¢ãã質åãžã®åçãªã©ïŒãæäŸããããšã§é¡§å®¢äœéšã®æ¹åãããããéèŠãåºãŠããå Žåããã®éèŠã«å¯Ÿå¿ã§ããŸããã ãã®ãããããã³ãããšã«ã«ã¹ã¿ãã€ãºãããLLMã·ã¹ãã ã®æ§ç¯ãéèŠãšãªããŸãã ããã³ãããšã®äœéšãæäŸããLLMã·ã¹ãã ããã³ãããšã®äœéšãæäŸããããã®ã¢ãããŒããšããŠãäžå³ã®ãããªRAGïŒRetrieval-Augmented GenerationïŒãšãã¡ã€ã³ãã¥ãŒãã³ã°ããããããŸãã RAG RAGãå©çšããå Žåã¯ããªã¯ãšã¹ãã®åºŠã«å€éšã®ããŒã¿ãœãŒã¹ããé¢é£æ
å ±ãæ€çŽ¢ãããã®æ
å ±ãããã³ããã«å«ããŠLLMã«éä¿¡ããããšã§ãããã³ãåºæã®æ
å ±ãæã£ãã¬ã¹ãã³ã¹ãçæããããšãã§ããŸãã æé ãšããŠã¯ä»¥äžã®ãããªã¹ããããèžã¿ãŸãã ããã³ãèå¥: JWTïŒJSON Web TokensïŒãªã©ãçšããŠãªã¯ãšã¹ããã©ã®ããã³ãããã®ãã®ããèå¥ããŸãã ããŒã¿æ€çŽ¢: JWTããæœåºã§ããããã³ãIDãåºã«ã該åœããããã³ãã®ããŒã¿ã«å¯ŸããŠãã¯ãã«æ€çŽ¢ãå®è¡ããŸãã ã³ã³ããã¹ãã®è¿œå : æ€çŽ¢çµæãšããŠåŸãããããã³ãåºæã®æ
å ±ã¯ãããã³ããã«è¿œå ããLLMã«éä¿¡ãããŸãã ãã ãã以äžã®ãããªèª²é¡ããããŸãã ã³ã¹ãïŒ RAGã§ã¯ãªã¯ãšã¹ãããšã«ããã³ãããšã³ã³ããã¹ããçµåããŠLLMã«ãéä¿¡ããå¿
èŠããããããããŒã¯ã³æ°ã®ã³ã¹ããå¢å ããå¯èœæ§ããããŸãã ç²ŸåºŠïŒ ããã³ãããšã³ã³ããã¹ãå
šäœã®ããŒã¯ã³æ°ãLLMã®èš±å®¹äžéãè¶
ããããšã§ããã£ã³ã¯åããéã®æç« ã®åãç®ãæªããªãåçã®ç²ŸåºŠãå£åããå¯èœæ§ããããŸãã ã¢ã¯ã»ã¹å¶åŸ¡ïŒå¥ã®é¡§å®¢ã®æ
å ±ãæµåºããŠããŸãã®ãé²ãããã«ãé©åãªããã³ãã®ããŒã¿ã«ã¢ã¯ã»ã¹ããããã«å¶åŸ¡ããªããã°ãªããŸããã ãã¡ã€ã³ãã¥ãŒãã³ã° ããã³ãåºæã®ããŒã¿ãçšããŠæ¢åã®LLMã¢ãã«ãååŠç¿ãããããšã§ããã®ããã³ãç¹æã®ç¥èãã¢ãã«ã«åã蟌ãããšãã§ããŸãã ãã¡ã€ã³ãã¥ãŒãã³ã°ãå©çšãããšãRAGã䜿ãããšãããã³ãåºæã®æ
å ±ãæäŸã§ããã®ãŠRAGã®ãã¡ãªãããäœæžã§ãããšããã¡ãªããããããŸãã ããããå瀟ããšã«LLMã¢ãã«ãäœæããããã€ãéçšããå¿
èŠãããããã管çãç
©éã«ãªã£ãŠããŸããšãããã¡ãªããããããŸãã RAGãšãã¡ã€ã³ãã¥ãŒãã³ã°ã®äœµçš RAGãšãã¡ã€ã³ãã¥ãŒãã³ã°ã¯æ±ºããŠæä»çãªãã®ã§ã¯ãªãããããã¯ãèŠæ±ã顧客ã®TierïŒäŸïŒæéãã©ã³ïŒã«å¿ããŠäœµçšãããšããèãæ¹ããããŸããè³æã§ã¯ã以äžã®éããTierã«å¿ããŠRAGãšãã¡ã€ã³ãã¥ãŒãã³ã°ã䜵çšããæ¹éã玹ä»ãããŠããã®ã§ãå
±æããŸãã Basic TierïŒäŸïŒæéãã©ã³ãäœãã®é¡§å®¢ïŒ: RAGãæŽ»çšããå
±éã®LLMã¢ãã«ãæäŸ Premium TierïŒäŸïŒæéãã©ã³ãé«ãã®é¡§å®¢ïŒ: ãã¡ã€ã³ãã¥ãŒãã³ã°ãæœããåå¥ã®LLMã¢ãã«ãæäŸ äœè«ïŒTierã«å¿ããŠå
±éã®ã¢ãã«ã䜿ããåå¥ã®ã¢ãã«ã䜿ããæ±ºãããšãããã®æ¹éã¯ãLLMã®ã¿ãªããæ©æ¢°åŠç¿ã¢ãã«ã«ãããŠãé©çšã§ããèãæ¹ã§ãããšãšãã«ã次ç¯ã®ãµã€ããšããŒã«ã®ã¡ãªãããããŸã享åãããã¡ãªãããããŸãå¶åŸ¡ã§ããã®ã§ãšãŠãåèã«ãªããŸããã ãµã€ããšããŒã« å
šããã³ãã§å
±éã®ã¢ãã«ããŸãã¯åå¥ã®ã¢ãã«ãæäŸããããã®åºæ¬çãªæŠå¿µãšããŠãäžå³ã§è¡šããããµã€ããšããŒã«ãšããã¢ãŒããã¯ãã£ãã¿ãŒã³ããããŸãã ãµã€ã åãã€ã¯ããµãŒãã¹ãäžã€ã®ããã³ããå æãããã¿ãŒã³ã§ãã ã¡ãªãã: ããŒã¿ãšããã³ããæç¢ºã«åé¢ã§ããã®ã§ãæ
å ±æŒæŽ©ã®ãªã¹ã¯ãäœãã§ãã 顧客ã®ã¢ããªã±ãŒã·ã§ã³ã®å©çšç¶æ³ãææ¡ãããããããã¯ã©ãŠããµãŒãã¹ãéããŠã¢ããªã±ãŒã·ã§ã³ãæäŸããŠããå Žåãå©çšã³ã¹ãã®ç®¡çã容æã§ãã ä»ããã³ãã«ãããã€ãžãŒãã€ããŒ(åŸè¿°)ã®åœ±é¿ãåããŸããã ãã¡ãªãã: ããã³ãæ°ãå¢å ãããšãåå¥ã®ã·ã¹ãã 倿Žãéçšãå¿
èŠãšãªãã管çã³ã¹ããå¢å ããŸãã ããŒã« åãã€ã¯ããµãŒãã¹ãå
šããã³ãã§å
±æãããã¿ãŒã³ã§ãã ã¡ãªãã: ç¹ã«å€æ°ã®ããã³ããååšããå Žåã管çã³ã¹ããæããããŸãã ãã¡ãªãã: ããã³ãããšã«ããŒã¿ãåé¢ããŠããããšã®ä¿èšŒãé£ãããããã³ãããšã®ã³ã¹ãææ¡ãå°é£ã§ãã äžéšã®ããã³ãã«ããéå°ãªãªãœãŒã¹å©çšïŒãã€ãžãŒãã€ããŒïŒãçºçããä»ããã³ãã®ãµãŒãã¹å質ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã ãããã®ãã¿ãŒã³ã¯æä»çãªãã®ã§ã¯ãªãããããã¯ãèŠæ±ãæè¡èŠä»¶ãªã©ã«åŸããã€ã¯ããµãŒãã¹ããšããã®äžã®ã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ãšã¹ãã¬ãŒãžããšã«ç¹ã亀ãããšãã£ã䜿ãåããçŸå®çã§ãã LLMã·ã¹ãã ãæ§ç¯ããéã®èæ
®äºé
å瀟åãããŸãã¯å
±éã®LLMãæäŸããéã«ã¯ã以äžã®ç¹ãéèŠãªèæ
®äºé
ãšãªããŸãã ããã³ãåé¢ ããŒã«ïŒå
±éLLMïŒã§æäŸããå Žåãåããã³ããé©åãªããŒã¿ã®ã¿ãåç
§ããŠããããšãä¿èšŒããå¿
èŠããããŸãã äŸãã°RAGã®å Žåãããã³ãããšã«ããŒã¯ã³ãååŸãããã®ããŒã¯ã³ã«åºã¥ããŠæ€çŽ¢ã€ã³ããã¯ã¹ãžã®ã¢ã¯ã»ã¹æš©éãå¶åŸ¡ãããªã©ã®ä»çµã¿ãå®è£
ããå¿
èŠããããŸãïŒåèè³æïŒRAG ã«ãããæ€çŽ¢ã·ã¹ãã ã®æš©éåé¢ãšè©äŸ¡ïŒã ã³ã¹ãèšç® ããã³ãããšã®LLMå©çšã³ã¹ãïŒäž»ã«å
¥åºåããŒã¯ã³æ°ïŒãææ¡ããããšã¯ãããžãã¹ãšãšã³ãžãã¢ãªã³ã°ã®äž¡é¢ã§éèŠã§ãã ããžãã¹èŠç¹: ããŒã¯ã³å©çšæãSaaSå©çšæãäžåã£ãŠããªããã確èªããåçæ§ãè©äŸ¡ããããã«å¿
èŠã§ãã ãšã³ãžãã¢ãªã³ã°èŠç¹: ã©ã®ããã³ããå€ãã®è² è·ããããŠããããææ¡ããããã«éèŠã§ãã ããŒã«æ§æã®å Žåãããã³ãããšã®ã³ã¹ãææ¡ã¯å°é£ã§ãããå©çšããŒã¯ã³æ°ãèšé²ãã以äžã®ãããªå°çšã®ã·ã¹ãã ãæ§ç¯ããå¿
èŠããããããããŸããã äžæ¹ããµã€ãæ§æã®å Žåãã¯ã©ãŠããµãŒãã¹ã®ã³ã³ãœãŒã«ãããã·ã¥ããŒãããããã³ãIDãæå®ãããšãã£ãããšã«ãããæ¯èŒç容æã«ã³ã¹ããææ¡ã§ããŸãã ãã€ãžãŒãã€ã㌠ãã«ãããã³ãSaaSã«ããããã€ãžãŒãã€ããŒãšã¯ãå°æ°ã®ããã³ããã·ã¹ãã å
šäœã®ãªãœãŒã¹ãéå°ã«å©çšããããšã§ãä»å€æ°ã®ããã³ããæ£åžžã«ãµãŒãã¹ãå©çšã§ããªããªãçŸè±¡ã§ãã LLMã«ãããŠãå
±éã¢ãã«ãå©çšããããã³ãã§çºçããããåŸåããããŸãã 察çãšããŠã¯ã¹ããããªã³ã°ïŒäŸïŒããã³ãããšãTierããšã«ããŒã¯ã³å©çšéã®äžéãèšå®ããïŒãæå¹ã«ãªããŸãã ãŸãšã ãã«ãããã³ãSaaSã«ãããLLMã·ã¹ãã ã¢ãŒããã¯ãã£ã®èšèšã«ãããŠã¯ãå
±éã®LLMã¢ãã«ãšåå¥ã®LLMã¢ãã«ã®äœ¿ãåããéèŠã§ãã䜿ãåãã®åºæºã®äžã€ãšããŠSaaSã®æéãã©ã³ãšãã£ãTierã«å¿ãã䜿ãåãããããŸãã å
±éã®LLMã¢ãã«: æéãã©ã³ãäœãã®ããã³ãã«å¯ŸããŠãRAGãå©çšããããšã§åå¥ã®äœéšãæäŸã§ããŸãã èæ
®äºé
ã¯ãåããã³ãã«å¯ŸããŠé©åãªããŒã¿ãåç
§ããŠãããä¿èšŒããããã®ã¢ã¯ã»ã¹ã³ã³ãããŒã«ãã³ã¹ãææ¡ã®ããã®å°çšã·ã¹ãã ã®æ§ç¯ããã€ãžãŒãã€ããŒå¯Ÿçã§ãã åå¥ã®LLMã¢ãã«: æéãã©ã³ãé«ãã®ããã³ãã«å¯ŸããŠããã¡ã€ã³ãã¥ãŒãã³ã°ããLLMãå©çšããããšã§ãåå¥ã®äœéšãæäŸã§ããŸãã èæ
®äºé
ã¯ã顧客ããšã«ã¢ãã«ãäœæããããã€ãéçšããå¿
èŠãããããã管çãç
©éã«ãªãã®ãé²ãæç«ãŠãçšæããŠããããšã§ãã
åç»
該åœããã³ã³ãã³ããèŠã€ãããŸããã§ãã









