้กน็›ฎๆ–‡ไปถๅคน

ๆ–‡ไปถ
wehub-resource-sync e06fe8e8c6
Secret Leaks / trufflehog (push) Failing after 1s
Build documentation / build (push) Failing after 1s
Build documentation / build_other_lang (push) Failing after 0s
CodeQL Security Analysis / CodeQL Analysis (push) Failing after 0s
PR CI / pr-ci (push) Failing after 1s
Slow tests on important models (on Push - A10) / Get all modified files (push) Failing after 1s
Slow tests on important models (on Push - A10) / Model CI (push) Has been skipped
Self-hosted runner (benchmark) / Benchmark (aws-g5-4xlarge-cache) (push) Has been cancelled
New model PR merged notification / Notify new model (push) Has been cancelled
Update Transformers metadata / build_and_package (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:57:37 +08:00

326 ่กŒ
21 KiB
Markdown

<!---
Copyright 2020 The HuggingFace Team. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
# ๐Ÿค— Transformers์— ๊ธฐ์—ฌํ•˜๊ธฐ [[contribute-to-transformers]]
๋ˆ„๊ตฌ๋‚˜ ๐Ÿค— Transformers์— ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ๊ธฐ์—ฌ๋ฅผ ์†Œ์ค‘ํžˆ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ๊ธฐ์—ฌ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋•๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค. ์งˆ๋ฌธ์— ๋‹ตํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ๋„์™€ ๋ฌธ์„œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ๋„ ๋งค์šฐ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๐Ÿค— Transformers๋ฅผ ๋„๋ฆฌ ์•Œ๋ฆฌ๋Š” ๊ฒƒ๋„ ํฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค! ๋ฉ‹์ง„ ํ”„๋กœ์ ํŠธ๋“ค์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ ๐Ÿค— Transformers ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€์— ์–ธ๊ธ‰ํ•˜๊ฑฐ๋‚˜, ๋„์›€์ด ๋˜์—ˆ์„ ๋•Œ๋งˆ๋‹ค Twitter์— ์•Œ๋ฆฌ๊ฑฐ๋‚˜, ์ €์žฅ์†Œ์— โญ๏ธ ๋ฅผ ํ‘œ์‹œํ•˜์—ฌ ๊ฐ์‚ฌ ์ธ์‚ฌ๋ฅผ ์ „ํ•ด์ฃผ์„ธ์š”.
์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๊ธฐ์—ฌํ•˜๋“  [ํ–‰๋™ ๊ทœ์น™](https://github.com/huggingface/transformers/blob/main/CODE_OF_CONDUCT.md)์„ ์ˆ™์ง€ํ•˜๊ณ  ์กด์ค‘ํ•ด์ฃผ์„ธ์š”.
**์ด ์•ˆ๋‚ด์„œ๋Š” ๋ฉ‹์ง„ [scikit-learn ๊ธฐ์—ฌ ์•ˆ๋‚ด์„œ](https://github.com/scikit-learn/scikit-learn/blob/main/CONTRIBUTING.md)์—์„œ ํฐ ์˜๊ฐ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.**
## ๊ธฐ์—ฌํ•˜๋Š” ๋ฐฉ๋ฒ• [[ways-to-contribute]]
์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๐Ÿค— Transformers์— ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* ๊ธฐ์กด ์ฝ”๋“œ์˜ ๋ฏธํ•ด๊ฒฐ๋œ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
* ๋ฒ„๊ทธ ๋˜๋Š” ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜๊ธธ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ์ด์Šˆ๋ฅผ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค.
* ์ƒˆ๋กœ์šด ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
* ์˜ˆ์ œ๋‚˜ ๋ฌธ์„œ์— ๊ธฐ์—ฌํ•ฉ๋‹ˆ๋‹ค.
์–ด๋””์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ• ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด, [Good First Issue](https://github.com/huggingface/transformers/contribute) ๋ชฉ๋ก์„ ํ™•์ธํ•ด๋ณด์„ธ์š”. ์ด ๋ชฉ๋ก์€ ์ดˆ๋ณด์ž๋„ ์ฐธ์—ฌํ•˜๊ธฐ ์‰ฌ์šด ์˜คํ”ˆ ์ด์Šˆ ๋ชฉ๋ก์„ ์ œ๊ณตํ•˜๋ฉฐ, ๋‹น์‹ ์ด ์˜คํ”ˆ์†Œ์Šค์— ์ฒ˜์Œ์œผ๋กœ ๊ธฐ์—ฌํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ์ € ์ž‘์—…ํ•˜๊ณ  ์‹ถ์€ ์ด์Šˆ์— ๋Œ“๊ธ€๋งŒ ๋‹ฌ์•„์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
์กฐ๊ธˆ ๋” ๋„์ „์ ์ธ ์ž‘์—…์„ ์›ํ•œ๋‹ค๋ฉด, [Good Second Issue](https://github.com/huggingface/transformers/labels/Good%20Second%20Issue) ๋ชฉ๋ก๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”. ์ด๋ฏธ ๋‹น์‹ ์ด ์ž˜ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋”๋ผ๋„, ํ•œ ๋ฒˆ ์‹œ๋„ํ•ด๋ณด์„ธ์š”! ์šฐ๋ฆฌ๋„ ์—ฌ๋Ÿฌ๋ถ„์„ ๋„์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๐Ÿš€
> ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ด๋ฃจ์–ด์ง€๋Š” ๋ชจ๋“  ๊ธฐ์—ฌ๋Š” ๋˜‘๊ฐ™์ด ์†Œ์ค‘ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿฅฐ
## ๋ฏธํ•ด๊ฒฐ๋œ ๋ฌธ์ œ ์ˆ˜์ •ํ•˜๊ธฐ [[fixing-outstanding-issues]]
๊ธฐ์กด ์ฝ”๋“œ์—์„œ ๋ฐœ๊ฒฌํ•œ ๋ฌธ์ œ์ ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋– ์˜ค๋ฅธ ๊ฒฝ์šฐ, ์–ธ์ œ๋“ ์ง€ [๊ธฐ์—ฌ๋ฅผ ์‹œ์ž‘](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md/#create-a-pull-request)ํ•˜๊ณ  Pull Request๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”!
## ๋ฒ„๊ทธ ๊ด€๋ จ ์ด์Šˆ๋ฅผ ์ œ๊ธฐํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์š”์ฒญํ•˜๊ธฐ [[submitting-a-bugrelated-issue-or-feature-request]]
๋ฒ„๊ทธ ๊ด€๋ จ ์ด์Šˆ๋ฅผ ์ œ๊ธฐํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์š”์ฒญํ•  ๋•Œ๋Š” ๋‹ค์Œ ๊ฐ€์ด๋“œ๋ผ์ธ์„ ์ตœ๋Œ€ํ•œ ์ค€์ˆ˜ํ•ด์ฃผ์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ข‹์€ ํ”ผ๋“œ๋ฐฑ๊ณผ ํ•จ๊ป˜ ๋น ๋ฅด๊ฒŒ ๋‹ต๋ณ€ํ•ด ๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜์…จ๋‚˜์š”? [[did-you-find-a-bug]]
๐Ÿค— Transformers ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‚ฌ์šฉ ์ค‘์— ๊ฒช๋Š” ๋ฌธ์ œ๋ฅผ ๋ณด๊ณ ํ•ด์ฃผ๋Š” ์‚ฌ์šฉ์ž๋“ค ๋•๋ถ„์— ๋”์šฑ ๊ฒฌ๊ณ ํ•ด์ง€๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ด์Šˆ๋ฅผ ๋ณด๊ณ ํ•˜๊ธฐ ์ „์—, ๋ฒ„๊ทธ๊ฐ€ ์ด๋ฏธ **๋ณด๊ณ ๋˜์ง€ ์•Š์•˜๋Š”์ง€** ํ™•์ธํ•ด์ฃผ์„ธ์š”. (GitHub์˜ ์ด์Šˆ ํƒญ ์•„๋ž˜์˜ ๊ฒ€์ƒ‰ ๋ฐ”๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”). ์ด์Šˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž์ฒด์—์„œ ๋ฐœ์ƒํ•œ ๋ฒ„๊ทธ์–ด์•ผ ํ•˜๋ฉฐ, ์ฝ”๋“œ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„๊ณผ ๊ด€๋ จ๋œ ๊ฒƒ์ด ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„๊ทธ๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฌธ์ œ๋กœ ๋ฐœ์ƒํ•˜์˜€๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋จผ์ € [ํฌ๋Ÿผ](https://discuss.huggingface.co/)์—์„œ ์งˆ๋ฌธํ•ด ์ฃผ์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ผ๋ฐ˜์ ์ธ ์งˆ๋ฌธ๋ณด๋‹ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๋” ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฒ„๊ทธ๊ฐ€ ์ด๋ฏธ ๋ณด๊ณ ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค๋ฉด, ๋‹ค์Œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์—ฌ ์ด์Šˆ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* ์‚ฌ์šฉ ์ค‘์ธ **์šด์˜์ฒด์ œ ์ข…๋ฅ˜์™€ ๋ฒ„์ „**, ๊ทธ๋ฆฌ๊ณ  **Python**, **PyTorch** ๋˜๋Š” **TensorFlow** ๋ฒ„์ „.
* ๋ฒ„๊ทธ๋ฅผ 30์ดˆ ์ด๋‚ด๋กœ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๋…๋ฆฝ์ ์ธ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ.
* ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ *์ „์ฒด* ํŠธ๋ ˆ์ด์Šค๋ฐฑ.
* ์Šคํฌ๋ฆฐ์ƒท๊ณผ ๊ฐ™์ด ๋„์›€์ด ๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋˜๋Š” ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ฒจ๋ถ€ํ•ด ์ฃผ์„ธ์š”.
์šด์˜์ฒด์ œ์™€ ์†Œํ”„ํŠธ์›จ์–ด ๋ฒ„์ „์„ ์ž๋™์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์„ธ์š”:
```bash
transformers env
```
์ €์žฅ์†Œ์˜ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋„ ๊ฐ™์€ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```bash
python src/transformers/commands/transformers_cli.py env
```
### ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์›ํ•˜์‹œ๋‚˜์š”? [[do-you-want-a-new-feature]]
๐Ÿค— Transformers์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค๋ฉด, ๋‹ค์Œ ๋‚ด์šฉ์„ ํฌํ•จํ•˜์—ฌ ์ด์Šˆ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”:
1. ์ด ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ *์ด์œ *๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”? ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ๋ฌธ์ œ๋‚˜ ๋ถˆ๋งŒ๊ณผ ๊ด€๋ จ์ด ์žˆ๋‚˜์š”? ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์ธ๊ฐ€์š”? ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋„์›€์ด ๋  ๋งŒํ•œ ๊ธฐ๋Šฅ์ธ๊ฐ€์š”?
์–ด๋–ค ๋‚ด์šฉ์ด๋“  ์—ฌ๋Ÿฌ๋ถ„์˜ ์ด์•ผ๊ธฐ๋ฅผ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค!
2. ์š”์ฒญํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ตœ๋Œ€ํ•œ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”. ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ• ์ˆ˜๋ก ๋” ๋‚˜์€ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
3. ํ•ด๋‹น ๊ธฐ๋Šฅ์˜ ์‚ฌ์šฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” *์ฝ”๋“œ ์Šค๋‹ˆํŽซ*์„ ์ œ๊ณตํ•ด ์ฃผ์„ธ์š”.
4. ๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ๋…ผ๋ฌธ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋งํฌ๋ฅผ ํฌํ•จํ•ด ์ฃผ์„ธ์š”.
์ด์Šˆ๊ฐ€ ์ž˜ ์ž‘์„ฑ๋˜์—ˆ๋‹ค๋ฉด ์ด์Šˆ๊ฐ€ ์ƒ์„ฑ๋œ ์ˆœ๊ฐ„, ์ด๋ฏธ 80% ์ •๋„์˜ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด์Šˆ๋ฅผ ์ œ๊ธฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๋งŒํ•œ [ํ…œํ”Œ๋ฆฟ](https://github.com/huggingface/transformers/tree/main/templates)๋„ ์ค€๋น„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
## ์ƒˆ๋กœ์šด ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? [[do-you-want-to-implement-a-new-model]]
์ƒˆ๋กœ์šด ๋ชจ๋ธ์€ ๊ณ„์†ํ•ด์„œ ์ถœ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์—ฌ๋Ÿฌ๋ถ„์ด ์ƒˆ๋กœ์šด ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด ์ฃผ์„ธ์š”:
* ๋ชจ๋ธ์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์„ค๋ช…๊ณผ ๋…ผ๋ฌธ ๋งํฌ.
* ๊ตฌํ˜„์ด ๊ณต๊ฐœ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ตฌํ˜„ ๋งํฌ.
* ๋ชจ๋ธ ๊ฐ€์ค‘์น˜๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๊ฐ€์ค‘์น˜ ๋งํฌ.
๋งŒ์•ฝ ๋ชจ๋ธ์„ ์ง์ ‘ ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด, ์•Œ๋ ค์ฃผ์„ธ์š”. ๐Ÿค— Transformers์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค!
[๐Ÿค— Transformers์— ์ƒˆ๋กœ์šด ๋ชจ๋ธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•](https://huggingface.co/docs/transformers/add_new_model)์— ๋Œ€ํ•œ ๊ธฐ์ˆ ์ ์ธ ์•ˆ๋‚ด์„œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
## ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? [[do-you-want-to-add-documentation]]
์šฐ๋ฆฌ๋Š” ์–ธ์ œ๋‚˜ ๋” ๋ช…ํ™•ํ•˜๊ณ  ์ •ํ™•ํ•œ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ฐœ์„ ์ ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜คํƒˆ์ž๋‚˜ ๋ถ€์กฑํ•œ ๋‚ด์šฉ, ๋ถ„๋ช…ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ถ€์ •ํ™•ํ•œ ๋‚ด์šฉ ๋“ฑ์„ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๊ธฐ์—ฌํ•˜์‹ค ์ˆ˜ ์žˆ๋„๋ก ๋„์™€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค!
๋ฌธ์„œ๋ฅผ ์ƒ์„ฑ, ๋นŒ๋“œ ๋ฐ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [README](https://github.com/huggingface/transformers/tree/main/docs) ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.
## ํ’€ ๋ฆฌํ€˜์ŠคํŠธ(Pull Request) ์ƒ์„ฑํ•˜๊ธฐ [[create-a-pull-request]]
์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— ๊ธฐ์กด์˜ Pull Request๋‚˜ ์ด์Šˆ๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฏธ ๋™์ผํ•œ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ํ™•์‹คํ•˜์ง€ ์•Š๋‹ค๋ฉด ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์ด์Šˆ๋ฅผ ์—ด์–ด๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
๐Ÿค— Transformers์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ๋ณธ์ ์ธ `git` ์‚ฌ์šฉ ๋Šฅ๋ ฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. `git`์€ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋„๊ตฌ๋Š” ์•„๋‹ˆ์ง€๋งŒ, ๋งค์šฐ ํ›Œ๋ฅญํ•œ ๋งค๋‰ด์–ผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์‰˜(shell)์—์„œ `git --help`์„ ์ž…๋ ฅํ•˜์—ฌ ํ™•์ธํ•ด๋ณด์„ธ์š”! ๋งŒ์•ฝ ์ฑ…์„ ์„ ํ˜ธํ•œ๋‹ค๋ฉด, [Pro Git](https://git-scm.com/book/en/v2)์€ ๋งค์šฐ ์ข‹์€ ์ฐธ๊ณ  ์ž๋ฃŒ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๐Ÿค— Transformers์— ๊ธฐ์—ฌํ•˜๋ ค๋ฉด **[Python 3.9](https://github.com/huggingface/transformers/blob/main/setup.py#L426)** ์ด์ƒ์˜ ๋ฒ„์ „์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์—ฌ๋ฅผ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”:
1. ์ €์žฅ์†Œ ํŽ˜์ด์ง€์—์„œ **[Fork](https://github.com/huggingface/transformers/fork)** ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์ €์žฅ์†Œ๋ฅผ ํฌํฌํ•˜์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ์˜ ๋ณต์‚ฌ๋ณธ์ด ์—ฌ๋Ÿฌ๋ถ„์˜ GitHub ์‚ฌ์šฉ์ž ๊ณ„์ • ์•„๋ž˜์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
2. ํฌํฌํ•œ ์ €์žฅ์†Œ๋ฅผ ๋กœ์ปฌ ๋””์Šคํฌ๋กœ ํด๋ก ํ•˜๊ณ , ๊ธฐ๋ณธ ์ €์žฅ์†Œ๋ฅผ ์›๊ฒฉ(remote)์œผ๋กœ ์ถ”๊ฐ€ํ•˜์„ธ์š”:
```bash
git clone git@github.com:<your Github handle>/transformers.git
cd transformers
git remote add upstream https://github.com/huggingface/transformers.git
```
3. ๊ฐœ๋ฐœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ €์žฅํ•  ์ƒˆ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:
```bash
git checkout -b a-descriptive-name-for-my-changes
```
๐Ÿšจ ์ ˆ๋Œ€ `main` ๋ธŒ๋žœ์น˜์—์„œ ์ž‘์—…ํ•˜์ง€ **๋งˆ์„ธ์š”!**
4. ๊ฐ€์ƒ ํ™˜๊ฒฝ์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜์„ธ์š”:
```bash
pip install -e ".[dev]"
```
๋งŒ์•ฝ ์ด๋ฏธ ๊ฐ€์ƒ ํ™˜๊ฒฝ์— ๐Ÿค— Transformers๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๋ฉด, `-e` ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜ํ•˜๊ธฐ ์ „์— `pip uninstall transformers`๋กœ ์ œ๊ฑฐํ•ด์ฃผ์„ธ์š”.
์—ฌ๋Ÿฌ๋ถ„์˜ ์šด์˜์ฒด์ œ์— ๋”ฐ๋ผ์„œ, ๊ทธ๋ฆฌ๊ณ  ๐Ÿค— Transformers์˜ ์„ ํƒ์  ์˜์กด์„ฑ์˜ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉด์„œ, ์ด ๋ช…๋ น์ด ์‹คํŒจํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋”ฅ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ(PyTorch, TensorFlow, ๊ทธ๋ฆฌ๊ณ /๋˜๋Š” Flax)๋ฅผ ์„ค์น˜ํ•œ ํ›„ ์•„๋ž˜ ๋ช…๋ น์„ ์‹คํ–‰ํ•ด์ฃผ์„ธ์š”:
```bash
pip install -e ".[quality]"
```
๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ด๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
5. ๋ธŒ๋žœ์น˜์—์„œ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜์„ธ์š”.
์ฝ”๋“œ๋ฅผ ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ(test suite)๊ฐ€ ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ์˜ํ–ฅ์„ ๋ฐ›๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”:
```bash
pytest tests/<TEST_TO_RUN>.py
```
ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” [ํ…Œ์ŠคํŠธ](https://huggingface.co/docs/transformers/testing) ๊ฐ€์ด๋“œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
๐Ÿค— Transformers๋Š” `black`๊ณผ `ruff`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค ์ฝ”๋“œ์˜ ํ˜•์‹์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•œ ํ›„์—๋Š” ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์ž๋™์œผ๋กœ ์Šคํƒ€์ผ ๊ต์ • ๋ฐ ์ฝ”๋“œ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•˜์„ธ์š”:
```bash
make style
```
์ด๊ฒƒ์€ ๋˜ํ•œ ์ž‘์—… ์ค‘์ธ PR์—์„œ ์ˆ˜์ •ํ•œ ํŒŒ์ผ์—์„œ๋งŒ ์ž‘๋™ํ•˜๋„๋ก ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฒ€์‚ฌ๋ฅผ ํ•˜๋‚˜์”ฉ ์‹คํ–‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์Šคํƒ€์ผ ๊ต์ •์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```bash
make style
```
๐Ÿค— Transformers๋Š” ๋˜ํ•œ `ruff`์™€ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์šฉ์ž ์ •์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋”ฉ ์‹ค์ˆ˜๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. CI๋ฅผ ํ†ตํ•ด ํ’ˆ์งˆ ๊ด€๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰๋˜์ง€๋งŒ, ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ๋™์ผํ•œ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```bash
make check-repo
```
์ด๋Ÿฌํ•œ ๊ฒ€์‚ฌ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ  ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ [Pull Request์— ๋Œ€ํ•œ ๊ฒ€์‚ฌ](https://huggingface.co/docs/transformers/pr_checks) ๊ฐ€์ด๋“œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
๋งŒ์•ฝ `docs/source` ๋””๋ ‰ํ„ฐ๋ฆฌ ์•„๋ž˜์˜ ๋ฌธ์„œ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฌธ์„œ๊ฐ€ ๋นŒ๋“œ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ์ด ๊ฒ€์‚ฌ๋Š” Pull Request๋ฅผ ์—ด ๋•Œ๋„ CI์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋ฌธ์„œ ๋นŒ๋”๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
```bash
pip install ".[docs]"
```
์ €์žฅ์†Œ์˜ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์„ธ์š”:
```bash
doc-builder build transformers docs/source/en --build_dir ~/tmp/test-build
```
์ด ๋ช…๋ น์€ `~/tmp/test-build` ํด๋”์— ๋ฌธ์„œ๋ฅผ ๋นŒ๋“œํ•˜๋ฉฐ, ์ƒ์„ฑ๋œ Markdown ํŒŒ์ผ์„ ์„ ํ˜ธํ•˜๋Š” ํŽธ์ง‘๊ธฐ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Pull Request๋ฅผ ์—ด ๋•Œ GitHub์—์„œ ๋ฌธ์„œ๋ฅผ ๋ฏธ๋ฆฌ ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋งŒ์กฑํ•˜๋ฉด `git add`๋กœ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ณ , `git commit`์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋กœ์ปฌ์— ๊ธฐ๋กํ•˜์„ธ์š”:
```bash
git add modified_file.py
git commit
```
[์ข‹์€ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€](https://chris.beams.io/posts/git-commit/)๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ „๋‹ฌํ•˜์„ธ์š”!
๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ”„๋กœ์ ํŠธ ์›๋ณธ ์ €์žฅ์†Œ์™€ ๋™๊ธฐํ™”ํ•˜๋ ค๋ฉด, PR์„ *์—ด๊ธฐ ์ „์—* ๋ธŒ๋žœ์น˜๋ฅผ `upstream/branch`๋กœ ๋ฆฌ๋ฒ ์ด์Šค(rebase)ํ•˜์„ธ์š”. ๋˜๋Š” ๊ด€๋ฆฌ์ž์˜ ์š”์ฒญ์— ์ด ์ž‘์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```bash
git fetch upstream
git rebase upstream/main
```
๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œํ•˜์„ธ์š”:
```bash
git push -u origin a-descriptive-name-for-my-changes
```
์ด๋ฏธ PR์„ ์—ด์—ˆ๋‹ค๋ฉด, `--force` ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๊ฐ•์ œ ํ‘ธ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„์ง PR์ด ์—ด๋ฆฌ์ง€ ์•Š์•˜๋‹ค๋ฉด ์ •์ƒ์ ์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ‘ธ์‹œํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
6. ์ด์ œ GitHub์—์„œ ํฌํฌํ•œ ์ €์žฅ์†Œ๋กœ ์ด๋™ํ•˜๊ณ  **Pull request(ํ’€ ๋ฆฌํ€˜์ŠคํŠธ)**๋ฅผ ํด๋ฆญํ•˜์—ฌ Pull Request๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์˜ [์ฒดํฌ๋ฆฌ์ŠคํŠธ](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md/#pull-request-checklist)์—์„œ ๋ชจ๋“  ํ•ญ๋ชฉ์— ์ฒดํฌ ํ‘œ์‹œ๋ฅผ ํ•˜์„ธ์š”. ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณด๋‚ด ๊ฒ€ํ† ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
7. ๊ด€๋ฆฌ์ž๊ฐ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์š”์ฒญํ•ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ ๊ธฐ์—ฌ์ž๋“ค๋„ ๋™์ผํ•œ ์ƒํ™ฉ์„ ๊ฒช์Šต๋‹ˆ๋‹ค! ๋ชจ๋‘๊ฐ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ Pull Request์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก, ๋กœ์ปฌ ๋ธŒ๋žœ์น˜์—์„œ ์ž‘์—…ํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํฌํ•œ ์ €์žฅ์†Œ๋กœ ํ‘ธ์‹œํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ž๋™์œผ๋กœ Pull Request์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
### Pull Request ์ฒดํฌ๋ฆฌ์ŠคํŠธ [[pull-request-checklist]]
โ˜ Pull Request ์ œ๋ชฉ์€ ๊ธฐ์—ฌ ๋‚ด์šฉ์„ ์š”์•ฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.<br>
โ˜ Pull Request๊ฐ€ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ, Pull Request ์„ค๋ช…์— ์ด์Šˆ ๋ฒˆํ˜ธ๋ฅผ ์–ธ๊ธ‰ํ•˜์—ฌ ์—ฐ๊ด€๋˜์–ด ์žˆ์Œ์„ ์•Œ๋ ค์ฃผ์„ธ์š”. (์ด์Šˆ๋ฅผ ํ™•์ธํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ํ•ด๋‹น ์ด์Šˆ์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ž„์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค).<br>
โ˜ ์ž‘์—…์ด ์ง„ํ–‰์ค‘์ด๋ผ๋ฉด ์ œ๋ชฉ ์•ž์— `[WIP]`๋ฅผ ๋ถ™์—ฌ์ฃผ์„ธ์š”. ์ค‘๋ณต ์ž‘์—…์„ ํ”ผํ•˜๊ณ  ๋ณ‘ํ•ฉํ•  ์ค€๋น„๊ฐ€ ๋œ PR๊ณผ ๊ตฌ๋ถ„ํ•˜๊ธฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.<br>
โ˜ ๊ธฐ์กด ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.<br>
โ˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.<br>
- ์ƒˆ ๋ชจ๋ธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ, `ModelTester.all_model_classes = (MyModel, MyModelWithLMHead,...)`์„ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•˜์„ธ์š”.
- ์ƒˆ `@slow` ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ, ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”: `RUN_SLOW=1 python -m pytest tests/models/my_new_model/test_my_new_model.py`.
- ์ƒˆ ํ† ํฌ๋‚˜์ด์ €๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ, ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”: `RUN_SLOW=1 python -m pytest tests/models/{your_model_name}/test_tokenization_{your_model_name}.py`.
- CircleCI์—์„œ๋Š” ๋А๋ฆฐ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์ง€๋งŒ, GitHub Actions์—์„œ๋Š” ๋งค์ผ ๋ฐค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค!<br>
โ˜ ๋ชจ๋“  ๊ณต๊ฐœ ๋ฉ”์†Œ๋“œ๋Š” ์œ ์šฉํ•œ ๊ธฐ์ˆ ๋ฌธ์„œ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค (์˜ˆ๋ฅผ ๋“ค์–ด [`modeling_bert.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/models/bert/modeling_bert.py) ์ฐธ์กฐ).<br>
โ˜ ์ €์žฅ์†Œ๊ฐ€ ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ €์žฅ์†Œ์— ์ƒ๋‹นํ•œ ๋ถ€๋‹ด์„ ์ฃผ๋Š” ์ด๋ฏธ์ง€, ๋™์˜์ƒ ๋ฐ ๊ธฐํƒ€ ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์€ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  [`hf-internal-testing`](https://huggingface.co/hf-internal-testing)๊ณผ ๊ฐ™์€ Hub ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ํŒŒ์ผ์„ ํ˜ธ์ŠคํŒ…ํ•˜๊ณ  URL๋กœ ์ฐธ์กฐํ•˜์„ธ์š”. ๋ฌธ์„œ์™€ ๊ด€๋ จ๋œ ์ด๋ฏธ์ง€๋Š” ๋‹ค์Œ ์ €์žฅ์†Œ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค: [huggingface/documentation-images](https://huggingface.co/datasets/huggingface/documentation-images). ์ด ๋ฐ์ดํ„ฐ์…‹ ์ €์žฅ์†Œ์—์„œ PR์„ ์—ด์–ด์„œ Hugging Face ๋ฉค๋ฒ„์—๊ฒŒ ๋ณ‘ํ•ฉ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Pull Request์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒ€์‚ฌ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” [Pull Request์— ๋Œ€ํ•œ ๊ฒ€์‚ฌ](https://huggingface.co/docs/transformers/pr_checks) ๊ฐ€์ด๋“œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
### ํ…Œ์ŠคํŠธ [[tests]]
๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋™์ž‘๊ณผ ์—ฌ๋Ÿฌ ์˜ˆ์ œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ๊ด‘๋ฒ”์œ„ํ•œ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ…Œ์ŠคํŠธ๋Š” [tests](https://github.com/huggingface/transformers/tree/main/tests) ํด๋”์—, ์˜ˆ์ œ ํ…Œ์ŠคํŠธ๋Š” [examples](https://github.com/huggingface/transformers/tree/main/examples) ํด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค.
์†๋„๊ฐ€ ๋น ๋ฅธ `pytest`์™€ `pytest-xdist`๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ €์žฅ์†Œ์˜ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  *ํ•˜์œ„ ํด๋” ๊ฒฝ๋กœ ๋˜๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ*๋ฅผ ์ง€์ •ํ•˜์„ธ์š”:
```bash
python -m pytest -n auto --dist=loadfile -s -v ./tests/models/my_new_model
```
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `examples` ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋„ *ํ•˜์œ„ ํด๋” ๊ฒฝ๋กœ ๋˜๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ*๋ฅผ ์ง€์ •ํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ๋ช…๋ น์€ PyTorch `examples` ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ํ•˜์œ„ ํด๋”๋ฅผ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค:
```bash
pip install -r examples/xxx/requirements.txt # only needed the first time
python -m pytest -n auto --dist=loadfile -s -v ./examples/pytorch/text-classification
```
์ด๊ฒƒ์ด ์‹ค์ œ๋กœ `make test` ๋ฐ `make test-examples` ๋ช…๋ น์ด ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค (`pip install`์€ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค)!
๋˜ํ•œ ํŠน์ • ๊ธฐ๋Šฅ๋งŒ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ๋” ์ž‘์€ ํ…Œ์ŠคํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ ๋А๋ฆฐ ํ…Œ์ŠคํŠธ๋Š” ๊ฑด๋„ˆ๋›ฐ์ง€๋งŒ `RUN_SLOW` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ `yes`๋กœ ์„ค์ •ํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋งŽ์€ ๊ธฐ๊ฐ€๋ฐ”์ดํŠธ ๋‹จ์œ„์˜ ๋ชจ๋ธ์ด ๋‹ค์šด๋กœ๋“œ๋˜๋ฏ€๋กœ ์ถฉ๋ถ„ํ•œ ๋””์Šคํฌ ๊ณต๊ฐ„, ์ข‹์€ ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ๊ณผ ๋งŽ์€ ์ธ๋‚ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!
<Tip warning={true}>
ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด *ํ•˜์œ„ ํด๋” ๊ฒฝ๋กœ ๋˜๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ*๋ฅผ ์ง€์ •ํ•˜์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `tests` ๋˜๋Š” `examples` ํด๋”์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜์–ด ๋งค์šฐ ๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค!
</Tip>
```bash
RUN_SLOW=yes python -m pytest -n auto --dist=loadfile -s -v ./tests/models/my_new_model
RUN_SLOW=yes python -m pytest -n auto --dist=loadfile -s -v ./examples/pytorch/text-classification
```
๋А๋ฆฐ ํ…Œ์ŠคํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ์ค‘์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š๋Š” ๋‹ค๋ฅธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
- `RUN_CUSTOM_TOKENIZERS`: ์‚ฌ์šฉ์ž ์ •์˜ ํ† ํฌ๋‚˜์ด์ € ํ…Œ์ŠคํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
๋” ๋งŽ์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์™€ ์ถ”๊ฐ€ ์ •๋ณด๋Š” [testing_utils.py](src/transformers/testing_utils.py)์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๐Ÿค— Transformers๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰๊ธฐ๋กœ `pytest`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ ์ž์ฒด์—์„œ๋Š” `pytest` ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ `unittest`๊ฐ€ ์™„์ „ํžˆ ์ง€์›๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ `unittest`๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค:
```bash
python -m unittest discover -s tests -t . -v
python -m unittest discover -s examples -t examples -v
```
### ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ [[style-guide]]
๋ฌธ์„œ๋Š” [Google Python ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ](https://google.github.io/styleguide/pyguide.html)๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [๋ฌธ์„œ ์ž‘์„ฑ ๊ฐ€์ด๋“œ](https://github.com/huggingface/transformers/tree/main/docs#writing-documentation---specification)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
### Windows์—์„œ ๊ฐœ๋ฐœ [[develop-on-windows]]
Windows์—์„œ ๊ฐœ๋ฐœํ•  ๊ฒฝ์šฐ([Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/) ๋˜๋Š” WSL์—์„œ ์ž‘์—…ํ•˜์ง€ ์•Š๋Š” ํ•œ) Windows `CRLF` ์ค„ ๋ฐ”๊ฟˆ์„ Linux `LF` ์ค„ ๋ฐ”๊ฟˆ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋„๋ก git์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
```bash
git config core.autocrlf input
```
Windows์—์„œ `make` ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ MSYS2๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:
1. [MSYS2](https://www.msys2.org/)๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. `C:\msys64`์— ์„ค์น˜๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
2. CLI์—์„œ `C:\msys64\msys2.exe`๋ฅผ ์—ฝ๋‹ˆ๋‹ค (์‹œ์ž‘ ๋ฉ”๋‰ด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์•ผ ํ•จ).
3. ์‰˜์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•˜์—ฌ: `pacman -Syu` ๋ฐ `pacman -S make`๋กœ `make`๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
4. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ PATH์— `C:\msys64\usr\bin`์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
์ด์ œ ๋ชจ๋“  ํ„ฐ๋ฏธ๋„ (PowerShell, cmd.exe ๋“ฑ)์—์„œ `make`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰
### ํฌํฌํ•œ ์ €์žฅ์†Œ๋ฅผ ์ƒ์œ„ ์›๋ณธ ๋ธŒ๋žœ์น˜(main)๊ณผ ๋™๊ธฐํ™”ํ•˜๊ธฐ (Hugging Face ์ €์žฅ์†Œ) [[sync-a-forked-repository-with-upstream-main-the-hugging-face-repository]]
ํฌํฌํ•œ ์ €์žฅ์†Œ์˜ main ๋ธŒ๋žœ์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ, ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ผ ์ˆ˜ํ–‰ํ•ด์ฃผ์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ upstream PR์— ์ฐธ์กฐ ๋…ธํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ณ  ์ด๋Ÿฌํ•œ PR์— ๊ด€์—ฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋ถˆํ•„์š”ํ•œ ์•Œ๋ฆผ์ด ์ „์†ก๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1. ๊ฐ€๋Šฅํ•˜๋ฉด ํฌํฌ๋œ ์ €์žฅ์†Œ์˜ ๋ธŒ๋žœ์น˜ ๋ฐ PR์„ ์‚ฌ์šฉํ•˜์—ฌ upstream๊ณผ ๋™๊ธฐํ™”ํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  ํฌํฌ๋œ main ์ €์žฅ์†Œ์— ์ง์ ‘ ๋ณ‘ํ•ฉํ•˜์„ธ์š”.
2. PR์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ๋ธŒ๋žœ์น˜๋ฅผ ํ™•์ธํ•œ ํ›„ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”:
```bash
git checkout -b your-branch-for-syncing
git pull --squash --no-commit upstream main
git commit -m '<your message without GitHub references>'
git push --set-upstream origin your-branch-for-syncing
```