File size: 6,147 Bytes
c13d23b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432f2a7
c13d23b
 
 
 
 
adcc53f
c13d23b
 
657ac04
 
 
adcc53f
 
657ac04
 
 
adcc53f
c13d23b
 
657ac04
 
c13d23b
 
 
657ac04
c13d23b
 
 
 
 
657ac04
c13d23b
 
657ac04
c13d23b
 
657ac04
c13d23b
 
adcc53f
 
c13d23b
 
adcc53f
 
 
 
 
c13d23b
 
657ac04
c13d23b
 
6d312fd
657ac04
6d312fd
 
657ac04
c13d23b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657ac04
c13d23b
 
 
 
 
 
657ac04
c13d23b
657ac04
c13d23b
 
 
 
 
 
 
 
 
 
 
 
 
 
657ac04
c13d23b
 
 
 
657ac04
c13d23b
657ac04
c13d23b
 
 
 
 
 
 
657ac04
c13d23b
 
657ac04
c13d23b
 
 
657ac04
c13d23b
 
 
 
 
 
 
657ac04
c13d23b
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        font-family: Arial, sans-serif;
      }
      input, button, progress {
        display: block;
        margin-top: 10px;
      }
      #message {
        margin-top: 20px;
        color: blue;
      }
      #error {
        color: red;
      }
    </style>
  </head>
  <body>
    <label for="tokenInput">Hugging Face Token:</label>
    <input type="password" id="tokenInput" name="tokenInput">
    <label for="repoInput">Repository ID:</label>
    <input type="text" id="repoInput" name="repoInput" placeholder="my-user/nlp-model">
    <input type="file" id="fileUpload" multiple>
    <button id="uploadButton">Upload Files</button>
    <div id="processingMessage"></div>
    <div style="display:flex"><progress id="progressBar" value="0" max="100"></progress><div id="uploadSpeed"></div></div>
    <div id="message"></div>
    <div id="error"></div>

    <script type="module">
      import { createRepo, uploadFiles } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/+esm";

      const uploadButton = document.getElementById('uploadButton');
      uploadButton.addEventListener('click', upload);
    
      // Override global fetch
      const originalFetch = window.fetch;
      let uploadStartTime;
      let uploadedBytes = 0;
    
      window.fetch = function(url, init) {
        if (typeof url === 'string' && init && init.method === 'PUT') {
          uploadStartTime = uploadStartTime || Date.now();
          return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open(init.method, url);
    
            for (let header in init.headers) {
              xhr.setRequestHeader(header, init.headers[header]);
            }
    
            xhr.onload = () => {
              resolve({
                ok: xhr.status >= 200 && xhr.status < 300,
                status: xhr.status,
                statusText: xhr.statusText,
                text: () => Promise.resolve(xhr.responseText),
              });
            };
    
            xhr.onerror = () => reject(new TypeError('Network request failed'));
            xhr.ontimeout = () => reject(new TypeError('Network request failed due to timeout'));
    
            xhr.upload.onprogress = (event) => {
              if (event.lengthComputable) {
                uploadedBytes += event.loaded;
                const progress = uploadedBytes / event.total;
                const progressBar = document.getElementById('progressBar');
                progressBar.value = progress * 100;
    
                const speedDiv = document.getElementById('uploadSpeed');
                const elapsedTime = (Date.now() - uploadStartTime) / 1000; // in seconds
                const speed = uploadedBytes / elapsedTime; // in bytes per second
                speedDiv.textContent = `Upload speed: ${(speed / 1024 / 1024).toFixed(2)} MB/s`;
              }
            };
    
            xhr.send(init.body);
          });
        } else {
          return originalFetch(url, init);
        }
      }
    
      async function upload() {
        const fileInput = document.getElementById('fileUpload');
        const files = Array.from(fileInput.files);
        const tokenInput = document.getElementById('tokenInput');
        const HF_ACCESS_TOKEN = tokenInput.value;
        const repoInput = document.getElementById('repoInput');
        const REPO_ID = repoInput.value;
        const progressBar = document.getElementById('progressBar');
        const messageDiv = document.getElementById('message');
        const errorDiv = document.getElementById('error');
        const processingMessage = document.getElementById('processingMessage');
        progressBar.value = 0;
        messageDiv.textContent = '';
        errorDiv.textContent = '';
        processingMessage.textContent = '';
    
        if (files.length > 0) {
          let totalSize = 0;
          for (let file of files) {
            totalSize += file.size;
          }
          totalSize = totalSize / (1024 * 1024);
    
          const startTime = Date.now();
    
          try {
            await createRepo({
              repo: REPO_ID,
              credentials: { accessToken: HF_ACCESS_TOKEN },
            });
          } catch (error) {
            if (error.message === 'You already created this model repo') {
              console.log('Repository already exists, proceeding to upload files');
            } else {
              console.error('Error creating repository', error);
              errorDiv.textContent = 'Error creating repository';
              return;
            }
          }
    
          try {
            await uploadFiles({
              repo: REPO_ID,
              credentials: { accessToken: HF_ACCESS_TOKEN },
              files: files.map(file => ({path: file.name, content: file}))
            });
    
            console.log(`All files uploaded successfully`);
            progressBar.value = 100;
          } catch (error) {
            console.error('Error uploading files', error);
            errorDiv.textContent = 'Error uploading files';
            return;
          }
    
          const elapsedTime = (Date.now() - startTime) / 1000;
          let speed = totalSize / elapsedTime;
    
          let time1GB = (1024 / speed) / 60;
          let time5GB = (5 * 1024 / speed) / 60;
          let time10GB = (10 * 1024 / speed) / 60;
    
          messageDiv.innerHTML = `All files uploaded successfully in ${elapsedTime.toFixed(2)} seconds, for all ${totalSize.toFixed(2)} MB in the ${files.length} files, speed ${speed.toFixed(2)} MB/s.<br>To upload a 1GB model at this speed, it would take approximately ${time1GB.toFixed(2)} minutes.<br>To upload a 5GB model at this speed, it would take approximately ${time5GB.toFixed(2)} minutes.<br>To upload a 10GB model at this speed, it would take approximately ${time10GB.toFixed(2)} minutes.`;
          processingMessage.textContent = "All files processed";
        } else {
          messageDiv.textContent = 'Please select files to upload';
        }
      }
    </script>

  </body>
</html>