config.yml 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. version: 2.1
  2. orbs:
  3. python: circleci/python@2
  4. jobs:
  5. unit_test:
  6. macos:
  7. xcode: "15.2.0"
  8. resource_class: macos.m1.medium.gen1
  9. steps:
  10. - checkout
  11. - run:
  12. name: Set up Python
  13. command: |
  14. brew install python@3.12
  15. python3.12 -m venv env
  16. source env/bin/activate
  17. - restore_cache:
  18. keys:
  19. - huggingface-hub-{{ checksum "~/.cache/huggingface/hub/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  20. - run:
  21. name: Install dependencies
  22. command: |
  23. source env/bin/activate
  24. pip install --upgrade pip
  25. pip install .
  26. - run:
  27. name: Run tests
  28. command: |
  29. source env/bin/activate
  30. ls ~/.cache/huggingface/hub/models--mlx-community--Meta-Llama-3-8B-Instruct-4bit/**/* || true
  31. METAL_XCODE=1 python3 -m exo.inference.test_inference_engine
  32. - save_cache:
  33. paths:
  34. - ~/.cache/huggingface/hub
  35. key: huggingface-hub-{{ checksum "~/.cache/huggingface/hub/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  36. discovery_integration_test:
  37. macos:
  38. xcode: "15.2.0"
  39. steps:
  40. - checkout
  41. - run:
  42. name: Set up Python
  43. command: |
  44. brew install python@3.12
  45. python3.12 -m venv env
  46. source env/bin/activate
  47. - run:
  48. name: Install dependencies
  49. command: |
  50. source env/bin/activate
  51. pip install --upgrade pip
  52. pip install .
  53. - run:
  54. name: Run discovery integration test
  55. command: |
  56. source env/bin/activate
  57. DEBUG_DISCOVERY=9 DEBUG=9 python3 main.py --node-id "node1" --listen-port 5678 --broadcast-port 5679 --chatgpt-api-port 8000 > output1.log 2>&1 &
  58. PID1=$!
  59. DEBUG_DISCOVERY=9 DEBUG=9 python3 main.py --node-id "node2" --listen-port 5679 --broadcast-port 5678 --chatgpt-api-port 8001 > output2.log 2>&1 &
  60. PID2=$!
  61. sleep 10
  62. kill $PID1 $PID2
  63. if grep -q "Connected to peer" output1.log && grep -q "Connected to peer" output2.log; then
  64. echo "Test passed: Both instances discovered each other"
  65. exit 0
  66. else
  67. echo "Test failed: Devices did not discover each other"
  68. echo "Output of first instance:"
  69. cat output1.log
  70. echo "Output of second instance:"
  71. cat output2.log
  72. exit 1
  73. fi
  74. chatgpt_api_integration_test:
  75. macos:
  76. xcode: "15.2.0"
  77. steps:
  78. - checkout
  79. - run:
  80. name: Set up Python
  81. command: |
  82. brew install python@3.12
  83. python3.12 -m venv env
  84. source env/bin/activate
  85. - restore_cache:
  86. keys:
  87. - huggingface-hub-{{ checksum "~/.cache/huggingface/hub/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  88. - huggingface-hub-
  89. - restore_cache:
  90. keys:
  91. - tinygrad-downloads-{{ checksum "~/Library/Caches/tinygrad/downloads/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  92. - tinygrad-downloads-
  93. - run:
  94. name: Install dependencies
  95. command: |
  96. source env/bin/activate
  97. pip install --upgrade pip
  98. pip install .
  99. - run:
  100. name: Run chatgpt api integration test
  101. command: |
  102. source env/bin/activate
  103. # Check if cached files are present
  104. ls ~/.cache/huggingface/hub/models--mlx-community--Meta-Llama-3-8B-Instruct-4bit/**/* || true
  105. # Start first instance
  106. DEBUG_DISCOVERY=9 DEBUG=9 python3 main.py --inference-engine mlx --node-id "node1" --listen-port 5678 --broadcast-port 5679 --chatgpt-api-port 8000 --chatgpt-api-response-timeout-secs 900 > output1.log 2>&1 &
  107. PID1=$!
  108. # Start second instance
  109. DEBUG_DISCOVERY=9 DEBUG=9 python3 main.py --inference-engine mlx --node-id "node2" --listen-port 5679 --broadcast-port 5678 --chatgpt-api-port 8001 --chatgpt-api-response-timeout-secs 900 > output2.log 2>&1 &
  110. PID2=$!
  111. # Wait for discovery
  112. sleep 10
  113. # Function to check if processes are still running
  114. check_processes() {
  115. if ! kill -0 $PID1 2>/dev/null; then
  116. echo "First instance (PID $PID1) died unexpectedly. Log output:"
  117. cat output1.log
  118. exit 1
  119. fi
  120. if ! kill -0 $PID2 2>/dev/null; then
  121. echo "Second instance (PID $PID2) died unexpectedly. Log output:"
  122. cat output2.log
  123. exit 1
  124. fi
  125. }
  126. # Check processes before proceeding
  127. check_processes
  128. # first one to load the model
  129. curl -s http://localhost:8000/v1/chat/completions \
  130. -H "Content-Type: application/json" \
  131. -d '{
  132. "model": "llama-3-8b",
  133. "messages": [{"role": "user", "content": "Keep responses concise. Placeholder to load model..."}],
  134. "temperature": 0.7
  135. }'
  136. # Check processes after model load
  137. check_processes
  138. response_1=$(curl -s http://localhost:8000/v1/chat/completions \
  139. -H "Content-Type: application/json" \
  140. -d '{
  141. "model": "llama-3-8b",
  142. "messages": [{"role": "user", "content": "Keep responses concise. Who was the king of pop?"}],
  143. "temperature": 0.7
  144. }')
  145. echo "Response 1: $response_1"
  146. # Check processes after first response
  147. check_processes
  148. response_2=$(curl -s http://localhost:8000/v1/chat/completions \
  149. -H "Content-Type: application/json" \
  150. -d '{
  151. "model": "llama-3-8b",
  152. "messages": [{"role": "user", "content": "Keep responses concise. Who was the king of pop?"}],
  153. "temperature": 0.7
  154. }')
  155. echo "Response 2: $response_2"
  156. # Check processes after second response
  157. check_processes
  158. # Stop both instances
  159. kill $PID1 $PID2
  160. echo ""
  161. if ! echo "$response_1" | grep -q "Michael Jackson" || ! echo "$response_2" | grep -q "Michael Jackson"; then
  162. echo "Test failed: Response does not contain 'Michael Jackson'"
  163. echo "Response 1: $response_1"
  164. echo ""
  165. echo "Response 2: $response_2"
  166. echo "Output of first instance:"
  167. cat output1.log
  168. echo "Output of second instance:"
  169. cat output2.log
  170. exit 1
  171. else
  172. echo "Test passed: Response from both nodes contains 'Michael Jackson'"
  173. fi
  174. - save_cache:
  175. paths:
  176. - ~/.cache/huggingface/hub
  177. key: huggingface-hub-{{ checksum "~/.cache/huggingface/hub/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  178. - save_cache:
  179. paths:
  180. - ~/Library/Caches/tinygrad/downloads
  181. key: tinygrad-downloads-{{ checksum "~/Library/Caches/tinygrad/downloads/**/*" }}-{{ .Environment.CIRCLE_JOB }}
  182. workflows:
  183. version: 2
  184. build_and_test:
  185. jobs:
  186. - unit_test
  187. - discovery_integration_test
  188. - chatgpt_api_integration_test